【问题标题】:JPA: Predicate and expression both in QueryCriteria where clauseJPA:QueryCriteria where 子句中的谓词和表达式
【发布时间】:2014-10-09 16:14:47
【问题描述】:

我的 where 子句中有一个谓词和表达式。并且两者都需要在 where 子句中进行与运算:

Expression<String> col1 = tableEntity.get("col1");
Expression<String> regExpr = criteriaBuilder.literal("\\.\\d+$");
Expression<Boolean> regExprLike = criteriaBuilder.function("regexp_like", Boolean.class, col, regExpr);

Expression<TableEntity> col2= tableEntity.get("col2");
Predicate predicateNull = criteriaBuilder.isNull(col2);

createQuery.where(cb.and(predicateNull));
createQuery.where(regExprLike);

在这种情况下,我无法执行以下操作: createQuery.where(predicateNull, regExprLike);

我尝试使用 CriteriaBuilder 的 isTrue() 方法:

Predicate predicateNull = criteriaBuilder.isNull(col2);
Predicate predicateTrue = criteriaBuilder.isTrue(regExprLike);
createQuery.where(predicateNull, predicateTrue);

但它没有帮助。

CriteriaQuery 允许在 where 子句中使用谓词或表达式,但不能同时使用两者。知道如何在 QueryCriteria 的 where 子句中同时使用谓词和表达式吗?

2014 年 10 月 10 日更新: 按照 Chris 的建议,我尝试使用:

createQuery.where(predicateNull, regExprLike);

但我的查询失败并出现异常:

Caused by: org.jboss.arquillian.test.spi.ArquillianProxyException: org.hibernate.hql.internal.ast.QuerySyntaxException : unexpected AST node: ( near line 1, column 311 [select coalesce(substring(generatedAlias0.col1,0,(locate(regexp_substr(generatedAlias0.col1, :param0),
generatedAlias0.col1)-1)), generatedAlias0.col1), generatedAlias0.col1 
from com.temp.TableEntity as generatedAlias0 
where (generatedAlias0.col2 is null ) and ( regexp_like(generatedAlias0.col1, :param1))] [Proxied because : Original exception not deserilizable, ClassNotFoundException]

我的代码如下:

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Object[]> createQuery = criteriaBuilder.createQuery(Object[].class);

Root<TableEntity> tableEntity = createQuery.from(TableEntity.class);

Expression<String> path = tableEntity.get("col1");

Expression<String> regExpr = criteriaBuilder.literal("\\.\\d+$");
Expression<String> regExprSubStr = criteriaBuilder.function("regexp_substr", String.class, path, regExpr);

Expression<Boolean> regExprLike = criteriaBuilder.function("regexp_like", Boolean.class, path, regExpr);


Expression<Integer> l3 = criteriaBuilder.locate(path, regExprSubStr);
Expression<Integer> minusOne = criteriaBuilder.literal(1);
Expression<Integer> l3Sub1 = criteriaBuilder.diff(l3, minusOne);
Expression<Integer> zeroIndex = criteriaBuilder.literal(0);
Expression<String> s3 = criteriaBuilder.substring(path, zeroIndex, l3Sub1);

Expression<TableEntity> col1 = tableEntity.get("col1");
Expression<TableEntity> col2 = tableEntity.get("col2");

Expression<String> coalesceExpr = criteriaBuilder.coalesce(s3, path);
createQuery.multiselect(coalesceExpr, col1);

Predicate predicateNull = criteriaBuilder.isNull(col2);

createQuery.where(criteriaBuilder.and(predicateNull, regExprLike));
String query = entityManager.createQuery(createQuery).unwrap(org.hibernate.Query.class).getQueryString();

【问题讨论】:

  • 您是否尝试过简单地将谓词和表达式相加? createQuery.where(criteriaBuilder.and(predicateNull, regExprLike));
  • 是的,我试过了。我没有收到任何编译时错误,但我的查询生成失败。我已经用最新的更新更新了我的问题。如果您有更多信息,请告诉我。谢谢。
  • @user613114 你有想过这个吗?
  • @Crystal,我当时想不通。所以我使用了本机查询实现。不知道有没有人发现。

标签: java jpa expression criteria predicate


【解决方案1】:

我认为您的问题是 oracle 没有将 'regexp_like' 归类为函数。要使其工作,您必须使用新的注册函数扩展 Oracle 方言:

 public class Oracle12cExtendedDialect extends Oracle12cDialect {

public Oracle12cExtendedDialect() {
    super();
    registerFunction(
            "regexp_like", new SQLFunctionTemplate(StandardBasicTypes.BOOLEAN,
                    "(case when (regexp_like(?1, ?2)) then 1 else 0 end)")
    );
}
}

然后你可以改变你的 where 子句:

        createQuery.where(criteriaBuilder.and(predicateNull, criteriaBuilder.equal(regExprLike, 1)));

当然,你必须在persistence.xml中注册你的新方言

            <property name="hibernate.dialect" value="path.to.your.dialect.class.Oracle12cExtendedDialect" />

【讨论】:

  • 不知何故,我认为您的方法给了我同样的错误,因为我尝试了“createQuery.where(criteriaBuilder.and(predicateNull, regExprLike))”。但我意识到我的错误,我完全按照建议进行了尝试。和 bammm .. 它就像一个魅力 :) 非常感谢您的时间和努力 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-18
  • 2022-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-25
  • 1970-01-01
相关资源
最近更新 更多