Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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
Jpa 使用条件api按集合字段的嵌套属性进行搜索_Jpa_Criteria_Criteria Api - Fatal编程技术网

Jpa 使用条件api按集合字段的嵌套属性进行搜索

Jpa 使用条件api按集合字段的嵌套属性进行搜索,jpa,criteria,criteria-api,Jpa,Criteria,Criteria Api,我试图找到所有有嵌套元素的实体,嵌套元素有元素集合,我需要通过这些集合的属性来找到它 应该是这样的 class A{ private B b; } class B{ private Collection<C> cCol; } class C{ private String name; } A类{ 私人B,; } B类{ 私人收藏cCol; } C类{ 私有字符串名称; } 所以我想得到所有A元素,其中B元素的名称与给定参数匹配的C元素 不知道如何使用JPA

我试图找到所有有嵌套元素的实体,嵌套元素有元素集合,我需要通过这些集合的属性来找到它

应该是这样的

class A{
    private B b;
}

class B{
   private Collection<C> cCol;
}

class C{
   private String name;
}
A类{
私人B,;
}
B类{
私人收藏cCol;
}
C类{
私有字符串名称;
}
所以我想得到所有A元素,其中B元素的名称与给定参数匹配的C元素

不知道如何使用JPA Critieria API实现。我知道在JPQL中有in谓词,或MEMEBER OF,但我需要按集合中元素的属性进行搜索,而不是集合成员

尝试了类似
root.get(a.b.c.name)
的方法,也尝试了
root.fetch(a.b)
root.fetch(b.c)
的方法,但总是以一些非法使用api的例外情况而告终

root.get("a").get("b").get("name")

我想得到所有A元素,其中B元素的名称与给定参数匹配的C元素

在尝试浏览CriteriaAPI时,我发现首先编写JPQL查询非常有用。这是:

SELECT a
FROM A a
WHERE EXISTS(
    SELECT c FROM a.b b JOIN b.cCol c WHERE c.name = 'condition'
)
现在标准API变得更清晰了(如果可能的话):

CriteriaBuilder cb=em.getCriteriaBuilder();
CriteriaQuery aQuery=cb.createQuery(A.class);
根a=aQuery.from(a.class);
子查询cSubquery=aQuery.Subquery(C.class);
根aSubroot=cSubquery.correlate(a);
Join b=aSubroot.Join(“b”);//“b”是指向b的A属性的名称
连接c=b。连接(“cCol”);//“cCol”是保存相关C对象的C属性的名称
cSubquery.select(c);
其中(cb.equal(c.get(“name”),“XXXXXXX”);
其中(cb.exists(cSubquery));
TypedQuery AtTypedQuery=em.createQuery(aQuery);
aTypedQuery.getResultList();

Java变量的名称与JPQL中的名称相同,例如,
Join b
对应于a.b中的JPQL

通过使用

root.**join**("a").get("b").get("name"):

因为它是一个集合。

从使用的字段名称来看,它应该是
root.get(“b”).get(“cCol”).get(“name”)
(假设
root
root
)。不幸的是,这失败了,出现了非法状态异常:非法尝试取消引用路径源[null.b.cCol]基本的type@Nadir-您可能应该发布更多关于如何创建查询的代码。我一直在尝试为此编写测试,但没有成功,因为get(“cCol”)实际上是一个集合。
aQuery.distinct(true).where(cb.equal(root.get(“b”).get(“cCol”).get(“name”),searchString))
也应该在不需要子查询的情况下给出相同的结果-等效的JPQL查询应该是
从a JOIN a.b JOIN b.cCol c中选择DISTINCT a,其中c.name=:searchString
我喜欢子查询而不是DISTINCT JOIN的原因是性能。虽然我不是这方面的专家,但以下是一些支持它的资源:。当然,实际结果和性能增益取决于确切的用例。
root.**join**("a").get("b").get("name"):