Quarkus3+Hibernate6中JPQL对tstzrange类型使用upper()/lower()函数问题
问题解决:Hibernate 6中JPQL处理PostgreSQL Range类型的upper/lower函数
在Hibernate 6.x中,JPQL默认不会将upper()/lower()识别为PostgreSQL Range类型的区间上下限函数——因为标准JPQL里这两个函数是专门用于字符串转大小写的,且Hibernate 6对函数参数的类型校验变得更严格,直接调用就会触发类型不匹配的错误。
解决方法有两种:
1. 自定义方言注册Range专属的upper/lower函数
扩展PostgreSQL方言,为Range类型单独注册upper和lower函数,让Hibernate能根据参数类型匹配到PostgreSQL的区间函数:
public class CustomPostgreSQLDialect extends PostgreSQLDialect { public CustomPostgreSQLDialect() { super(); // 注册针对Range类型的upper函数,映射到PostgreSQL的upper(range) registerFunction( "upper", new StandardSQLFunction( "upper", null, List.of(RangeType.INSTANCE) ) ); // 注册针对Range类型的lower函数,映射到PostgreSQL的lower(range) registerFunction( "lower", new StandardSQLFunction( "lower", null, List.of(RangeType.INSTANCE) ) ); } }
然后在Quarkus配置文件中指定使用这个自定义方言:
quarkus.hibernate-orm.dialect=com.your.package.CustomPostgreSQLDialect
2. 改用原生SQL查询
直接编写PostgreSQL原生SQL,绕开JPQL的函数映射限制:
List<Restriction> resultList = entityManager.createNativeQuery( "SELECT * FROM age_restriction WHERE upper(range_zoned_date_time) IS NOT NULL", Restriction.class ).getResultList();
补充说明
hypersistence-utils的Hibernate 6版本并未自动注册这些Range函数,需要手动扩展方言来实现JPQL层面的函数支持。Hibernate 6的函数解析机制更关注参数类型匹配,所以必须明确为Range类型注册同名函数,才能覆盖默认的字符串函数逻辑。
内容的提问来源于stack exchange,提问作者Michal Drozd
相关产品推荐
相关产品推荐

