【发布时间】:2014-08-28 17:43:57
【问题描述】:
我正在尝试使用 JPA CriteriaBuilder 为名为“TestContact”的实体生成查询,该实体与另一个名为“SystemGroup”的实体具有多对多连接,该连接的属性称为“组”。查询的目的是从“groups”属性在列表中或为空的“TestContact”实体中检索记录。
我使用的代码如下
public List<TestContact> findWithCriteriaQuery(List<SystemGroup> groups) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<TestContact> cq = cb.createQuery(TestContact.class);
Root<TestContact> testContact = cq.from(TestContact.class);
cq.select(testContact);
Path<List<SystemGroup>> groupPath = testContact.get("groups");
// cq.where(groupPath.in(groups));
// cq.where(cb.isEmpty(groupPath));
cq.where(cb.or(cb.isEmpty(groupPath), groupPath.in(groups)));
TypedQuery<TestContact> tq = em.createQuery(cq);
return tq.getResultList();
}
问题是这个查询只返回组在列表“组”中的结果,但由于某种原因,它也没有返回组为空的结果(即连接表中没有条目)
如果我将 where 子句更改为 cq.where(cb.isEmpty(groupPath));,那么查询会正确返回 group 为空的结果。
如果我将 where 子句更改为 cq.where(groupPath.in(groups));,则查询会正确返回组在列表“组”中的结果。
我不明白为什么当我尝试使用 CriteriaBuilder 或方法组合这两个谓词时,结果不包括组在列表中或为空的记录。
“TestContact”实体中的groups属性声明如下
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name = "TEST_CONTACT_GROUPS", joinColumns = { @JoinColumn(name = "CONTACT_ID", referencedColumnName = "CONTACT_ID") }, inverseJoinColumns = { @JoinColumn(name = "GROUP_ID", referencedColumnName = "GROUP_ID") })
private List<SystemGroup> groups;
JPA 提供程序是 EclipseLink 2.5.0,Java EE 应用服务器是 GlassFish 4,数据库是 Oracle 11gR2。
谁能指出我哪里出错了?
更新
我尝试了@Chris 的建议,但 Eclipse 在Join<List<SystemGroup>> groupPath = testContact.join("groups", JoinType.LEFT) 上返回以下错误
类型 Join 的参数数量不正确;它不可能是 参数化参数 >
查看Join 的JavaDoc,它说类型参数是......
Z - 连接的源类型,X - 连接的目标类型
我尝试了Join<TestContact, SystemGroup> groupPath = testContact.join("groups", JoinType.LEFT);,然后导致 Eclipse 在cb.isEmpty 上返回以下错误
绑定不匹配:类型的泛型方法isEmpty(Expression) CriteriaBuilder 不适用于参数 (加入)。推断的类型 SystemGroup 不是 有界参数的有效替代>
【问题讨论】:
标签: java jpa eclipselink criteria-api