java - 是否可以避免在 HQL 查询的“where”子句中为布尔函数添加“= true”
问题描述
我正在使用 PostgreSQL 和 JPA/Hibernate。我需要构建一个包含 PostgreSQL 正则表达式比较运算符的 HQL 查询(name ~ 'pattern'
)。我有以下方言:
public class PostgreSQLExtendedDialect extends PostgreSQL95Dialect {
public PostgreSQLExtendedDialect() {
registerFunction("regexp_matches", new SQLFunctionTemplate(BooleanType.INSTANCE, "(?1 ~ ?2)"));
}
}
但是,以下查询...
entityManager.createQuery("select p from Person p where regexp_matches(p.name, ?1)")
.setParameter(1, "qwe")
.getResultList();
...失败,但有以下异常:
antlr.NoViableAltException: unexpected AST node: (
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2146)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:815)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:609)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:313)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:261)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:271)
同时,以下查询...
entityManager.createQuery("select p from Person p where regexp_matches(p.name, ?1) = true")
.setParameter(1, "qwe")
.getResultList();
... 有效,但会产生以下奇怪的 SQL:
where
person0_.name ~ ?=true
我想知道是否可以避免向已经是布尔表达式的 HQL 部分添加奇怪的“= true”后缀。理想情况下,也许有一些只注册运算符的能力,这样我就可以直接在 HQL 中编写“p.name ~ ?1”。
注意。我知道我可以编写原生查询,但是我有相当复杂的 HQL 查询,这在 SQL 版本中将是一个巨大的巨人,所以我需要保留 HQL。
谢谢!
解决方案
这是不可能的。Mabye 在 Hibernate 6 中,但之前没有办法这样做,因为函数总是应该产生标量值,如果你需要一个谓词,你需要使用一个 JPQL/HQL 谓词。
您可以引入一个自定义SQLFunction
实现来呈现 HQL 函数调用regexp_matches(p.name, ?1)
,regexp_matches(p.name, ?1) and true =
以便regexp_matches(p.name, ?1) and true = true
在使用regexp_matches(p.name, ?1) = true
.
PostgreSQL 可以优化掉重言式true = true
。
推荐阅读
- javascript - 使用 Mocha 和 Express Rest API 进行单元测试
- javascript - 如何在jquery中获取带有id的td的值
- openssl - OpenSSL 规范化
- linux - lua:bad argument #2 to '?'(start index out of bound)
- php - 在查询 Laravel 5.2 中将 varchar 转换为日期
- pega - 将值从子案例复制到父案例,出现错误
- sql - SQL Server 2012:比较和减去连接中的日期
- sql - 同一表上的多个连接给出重复数据
- jsf-2 - 将参数传递给复合组件的验证器
- sql - 使用 Postgres regexp_replace 屏蔽查询字符串参数值