我试图使用JPA CriteriaBuilder生成名为“TestContact”有一个实体的查询的多到多用所谓的“SystemGroup”其中,此属性联接所谓的“团体”另一个实体加盟。 查询的目的是从这里的“组”属性为列表或为空的“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));
那么查询正确返回结果,其中组是空的。
如果我改变where子句cq.where(groupPath.in(groups));
那么该查询返回正确的结果,其中组是在列表中的“组”。
我不明白的是,为什么当我尝试使用CriteriaBuilder或方法的结果不包括在记录中,其中基团是在列表或者是空的这两个谓词结合起来。
该集团在“TestContact”实体属性的声明如下
@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的。
任何人都可以请指出我要去哪里错了吗?
更新
我试着从@克里斯的建议,但Eclipse是返回以下错误Join<List<SystemGroup>> groupPath = testContact.join("groups", JoinType.LEFT)
的类型参数的注册数目不正确; 它不能与参数进行参数>
纵观JavaDoc中Join
它说的类型参数...
ž - 联接,X的源类型 - 目标类型的联接
我试图Join<TestContact, SystemGroup> groupPath = testContact.join("groups", JoinType.LEFT);
然后使Eclipse来回报下列错误cb.isEmpty
绑定不匹配:类型CriteriaBuilder的一般方法的isEmpty(表达)是不适用的参数(加入)。 推断出的类型SystemGroup不是用于有界参数的有效替代>