Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JPA CriteriaBuilder生成属性在列表中或为空的查询_Java_Jpa_Eclipselink_Criteria Api - Fatal编程技术网

Java 使用JPA CriteriaBuilder生成属性在列表中或为空的查询

Java 使用JPA CriteriaBuilder生成属性在列表中或为空的查询,java,jpa,eclipselink,criteria-api,Java,Jpa,Eclipselink,Criteria Api,我试图使用JPA CriteriaBuilder为一个名为“TestContact”的实体生成一个查询,该实体与另一个名为“SystemGroup”的实体有多对多连接,其中该连接的属性称为“groups”。查询的目的是从“TestContact”实体中检索记录,其中“groups”属性在列表中或为空 我使用的代码如下 public List<TestContact> findWithCriteriaQuery(List<SystemGroup> groups) {

我试图使用JPA CriteriaBuilder为一个名为“TestContact”的实体生成一个查询,该实体与另一个名为“SystemGroup”的实体有多对多连接,其中该连接的属性称为“groups”。查询的目的是从“TestContact”实体中检索记录,其中“groups”属性在列表中或为空

我使用的代码如下

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();
}
@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在
joingrouppath=testContact.Join(“groups”,JoinType.LEFT)

类型Join的参数数目不正确;不可能 参数化参数>

查看JavaDoc for
Join
它说类型参数是

Z-连接的源类型,X-连接的目标类型

我已经尝试了
joingrouppath=testContact.Join(“groups”,JoinType.LEFT)
这会导致Eclipse在
cb.isEmpty上返回以下错误

绑定不匹配:泛型方法为类型为的空(表达式) CriteriaBuilder不适用于参数 (加入)。推断的类型SystemGroup不正确 有界参数的有效替代项>

testContact.get(“组”);子句强制从testContact到组的内部联接,这将过滤掉没有组的testContacts。您需要指定一个左外部联接,并在isEmpty和in子句中使用它

Root<TestContact> testContact = cq.from(TestContact.class);
cq.select(testContact);

Join<TestContact, SystemGroup> groupPath = testContact.join("groups", JoinType.LEFT);
cq.where(cb.or(cb.isEmpty(testContact.get("groups")), groupPath.in(groups)));
Root testContact=cq.from(testContact.class);
cq.select(testContact);
Join groupPath=testContact.Join(“组”,JoinType.LEFT);
cq.where(cb.or(cb.isEmpty(testContact.get(“groups”)),groupPath.in(groups));

我通常参考示例

谢谢-我尝试了你的建议,但在
Join groupPath=testContact.Join(“groups”,JoinType.LEFT)上出现错误。我已经更新了原始问题的一些细节。有什么想法吗?我没有一个测试项目可以先试一下。我已经更新了这个示例,现在应该可以使用了-我相信JPA应该使用.get(“groups”)来创建子查询,而外部连接到“in”子句的关系。Eclipse报告说,
.isEmpty()
不是
testContact.get(“groups”)的方法。Eclipse建议将其强制转换为CriteriaBuilder,但如果我尝试这样做,Eclipse会在
.isEmpty()
方法上出现“绑定不匹配错误”。我最后使用的代码是
Root testContact=cq.from(testContact.class);cq.select(testContact);Path groupPath1=testContact.get(“组”);ListJoin groupPath2=testContact.joinList(“组”,JoinType.LEFT);cq.where(cb.or(cb.isEmpty(groupPath1),groupPath2.in(groups))