Hibernate 6为自定义用户类型使用了错误的JdbcType

qnzebej0  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(162)

我有一个使用Quarkus 3.1.2.Final的项目,它在6.2.4.Final版本中使用hibernate-core
这里我有一个自定义类的自定义用户类型,它在实体中使用。

@Type(MyStringUserType.class)
public MyStringWrapper field;

字符串
当我执行一个条件查询时,它使用了像uppersubstring等函数。我有个例外。
范例

@Transactional
List<MyEntity> getByQuery() {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<MyEntity> query = cb.createQuery(MyEntity.class);
    Root<MyEntity> root = query.from(MyEntity.class);

    query.where(
            cb.equal(cb.upper(root.get("field")), new MyStringWrapper("SOME VALUE"))
    );
    TypedQuery<MyEntity> result = em.createQuery(query);
    return result.getResultList();
}


例外情况:
[ERROR] org. acme. UserTypeTest. testQuery经过的时间:0.129秒<错误!
org.hibernate.QueryException:函数upper()的参数1的类型为STRING,但参数的类型为org.acme.MyStringWrapper
在org. hibernate 查询。平方米。生产。功能ArgumentTypesValidator。throwError(ArgumentTypesValidator.java:253)at org. hibernate 查询。平方米。生产。功能ArgumentTypesValidator。org上的checkType(ArgumentTypesValidator.java:204)。 hibernate 查询。平方米。生产。功能ArgumentTypesValidator。validate(ArgumentTypesValidator.java:98)at org. hibernate 查询。平方米。功能AbstractSqmFunctionDescriptor。generateSqmExpression(AbstractSqmFunctionDescriptor.java:104)at org. hibernate 查询。平方米。功能SqmFunctionDescriptor。org上的generateSqmExpression(SqmFunctionDescriptor.java:117)。 hibernate 查询。平方米。内部的SqmCriteriaNodeBuilder。upper(SqmCriteriaNodeBuilder.java:1541)at org. hibernate 查询。平方米。内部的SqmCriteriaNodeBuilder。upper(SqmCriteriaNodeBuilder.java:182)at org.极致UserTypeTestBean。getByQuery(UserTypeTestBean.java:34)at org.极致UserTypeTestBean_Subclass. getByQuery $$superforward(Unknown Source)at org.acme.UserTypeTestBean_Subclass$$function$$1.apply(Unknown Source)[...]
当我在Hibernate 5中做同样的事情时,它工作得很好。
我有两个复制者:

有没有机会让这样一个星座运行在Hibernate 6上?
目前我通过调试发现
被调用的方法org.hibernate.query.sqm.produce.function.ArgumentTypesValidator#getJdbcType返回一个VarbinaryJdbcType,然后导致org.hibernate.query.sqm.produce.function.ArgumentTypesValidator#checkType中的一个错误(抛出),因为Varbinary不是字符类型。
这里我希望使用VarcharJdbcType,因为在我的自定义用户类型中,getSqlType返回java.sql.Types.VARCHAR
我还尝试使用@JdbcType(VarcharJdbcType.class)@JdbcTypeCode(Types.VARCHAR)定义类型,但没有任何变化。

1zmg4dgp

1zmg4dgp1#

同时我发现了一个hacky的解决方法,但目前我不知道后果-但至少我的例子可以用这个。
如果将属性转换器添加到实体中的属性中(或像下面的示例中那样全局定义),则仍然使用用户类型,并且不调用属性转换器方法(!)。但是它现在使用的是VarcharJdbcType,而不是像我描述中提到的VarbinaryJdbcType

@Converter(autoApply = true)
public class DummyConverter implements AttributeConverter<MyStringWrapper, String> {

    @Override
    public String convertToDatabaseColumn(final MyStringWrapper o) {
        throw new RuntimeException("dummy converter should not be called");
    }

    @Override
    public MyStringWrapper convertToEntityAttribute(final String o) {
        throw new RuntimeException("dummy converter should not be called");
    }
}

字符串
我必须调查可能的副作用,但至少我的查询可以处理这个问题。也许这些信息可以帮助一些人-也可能是Hibernate开发人员。
但是在最后,Hibernate应该解决这个问题(HHH-16751)。

相关问题