我有一个使用Quarkus 3.1.2.Final的项目,它在6.2.4.Final版本中使用hibernate-core
。
这里我有一个自定义类的自定义用户类型,它在实体中使用。
@Type(MyStringUserType.class)
public MyStringWrapper field;
字符串
当我执行一个条件查询时,它使用了像upper
、substring
等函数。我有个例外。
范例
@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中做同样的事情时,它工作得很好。
我有两个复制者:
- https://github.com/timonzi/hibernate-user-type-query-reproducer
- https://github.com/timonzi/hibernate-user-type-query-reproducer-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)
定义类型,但没有任何变化。
1条答案
按热度按时间1zmg4dgp1#
同时我发现了一个hacky的解决方法,但目前我不知道后果-但至少我的例子可以用这个。
如果将属性转换器添加到实体中的属性中(或像下面的示例中那样全局定义),则仍然使用用户类型,并且不调用属性转换器方法(!)。但是它现在使用的是
VarcharJdbcType
,而不是像我描述中提到的VarbinaryJdbcType
。字符串
我必须调查可能的副作用,但至少我的查询可以处理这个问题。也许这些信息可以帮助一些人-也可能是Hibernate开发人员。
但是在最后,Hibernate应该解决这个问题(HHH-16751)。