JPA Criteria API IN 表达式 参数列表

Posted

技术标签:

【中文标题】JPA Criteria API IN 表达式 参数列表【英文标题】:JPA Criteria API IN expression Parameter list 【发布时间】:2012-05-30 18:29:15 【问题描述】:

是否可以在 Criteria API .in 表达式中使用参数列表?

我有这样的事情:

    List<Long> list = new ArrayList<Long>();
    list.add((long)1);
    list.add((long)2);
    list.add((long)3);


CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Bewerbung> criteriaQuery = cb.createQuery(Bewerbung.class);
Root<Bewerbung> bewerbung = criteriaQuery.from(Bewerbung.class);

criteriaQuery.select(bewerbung).where(
cb.in(bewerbung.get(Bewerbung_.bewerberNummer)).value(list);

return em.createQuery(criteriaQuery).getResultList();

表达式 .value(list) 不起作用,因为 value() 需要一个 long 类型的参数而不是列表。 就我而言,不可能使用子查询。 谁能帮我解决这个问题?

【问题讨论】:

【参考方案1】:

无需使用CriteriaBuilder#isTrue。这应该足够了:

criteriaQuery.select(bewerbung)
             .where(bewerbung.get(Bewerbung_.bewerberNummer)
             .in(list));

【讨论】:

我不会说“不需要”,而是说“一定不要”。至少肯定使用 EclipseLink 2.6.2。我已经测试过了。 @MiklosKrivan 很好,两者都应该工作,这对我来说看起来更清楚。 我也希望如此,但不幸的是,将 EclipseLink 2.6.2 用于 ORM(我已经尝试了这两个公式) isTrue() 包装引发了上述异常。这就是我给出措辞建议的原因。所以理论上“不需要”,但实际上“绝对不能”。 @MiklosKrivan 将不得不检查,感谢澄清。 @MiklosKrivan 如果可能的话,请您在pastebin 或其他地方分享您的堆栈跟踪吗?【参考方案2】:
cb.isTrue(bewerbung.get(Bewerbung_.bewerberNummer).in(list));

应该做的伎俩,AFAIK。

【讨论】:

太好了,谢谢这个作品,但我正在使用 Hibernate,而且似乎 Hibernate 不支持空集合作为 javax.persistence.criteria.Expression "in" 方法参数的参数。见lists.jboss.org/pipermail/hibernate-issues/2011-December/… AFAIK,没有人支持他们。如果将空列表作为参数传递,您可能应该缩短查询。 我发现这个表达式(包装在 isTrue 中)在 EclipseLink 2.6.2 中引发异常 PREDICATE_PASSED_TO_EVALUATION 但没有 isTrue 包装在我的示例中完美作为谓词可能是因为“in”返回 Predicate 对象。

以上是关于JPA Criteria API IN 表达式 参数列表的主要内容,如果未能解决你的问题,请参考以下文章

JPA 如何获取 Criteria API 中使用的参数标记的数量?

比较 JPA Criteria API 中的日期实体

使用 JPA 的 Criteria API 按日期间隔分组

JPA & Criteria API - 仅选择特定列

jpa criteria-api:加入子选择

JPA/Criteria API - Like & equal 问题