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

Nad*_*dir 2 jpa criteria criteria-api

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

这将是这样的

class A{
    private B b;
}

class B{
   private Collection<C> cCol;
}

class C{
   private String name;
}
Run Code Online (Sandbox Code Playgroud)

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

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

尝试之类的东西root.get(a.b.c.name),也有root.fetch(a.b)root.fetch(b.c)但总是结束了与非法API使用一些例外

Nik*_*los 9

我想获得所有具有B元素的A元素,这些元素具有与给定参数匹配的C.

在尝试浏览条件API时,我发现首先编写JPQL查询非常有帮助.这里是:

SELECT a
FROM A a
WHERE EXISTS(
    SELECT c FROM a.b b JOIN b.cCol c WHERE c.name = 'condition'
)
Run Code Online (Sandbox Code Playgroud)

现在标准API变得更加清晰(如果可能的话):

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<A> aQuery = cb.createQuery(A.class);
Root<A> a = aQuery.from(A.class);

Subquery<C> cSubquery = aQuery.subquery(C.class);
Root<A> aSubroot = cSubquery.correlate(a);
Join<A, B> b = aSubroot.join("b");  // "b" is the name of the property of A that points to B
Join<B, C> c = b.join("cCol"); // "cCol" is the name of the property of C that holds the related C objects

cSubquery.select(c);
cSubquery.where(cb.equal(c.get("name"), "XXXXXXX"));

aQuery.where(cb.exists(cSubquery));

TypedQuery<A> aTypedQuery = em.createQuery(aQuery);
aTypedQuery.getResultList();
Run Code Online (Sandbox Code Playgroud)

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


Ess*_*Boy 5

下面应该工作

root.get("a").get("b").get("name")
Run Code Online (Sandbox Code Playgroud)

看到

如何通过组合表使用JpaSpecificationExecutor创建规范?

  • 不幸的是,这失败,并出现IllegalStateException:非法尝试取消引用基本类型的路径源[null.b.cCol] (4认同)
  • 在使用的字段名称中,它应该是`root.get(“ b”)。get(“ cCol”)。get(“ name”)`(假设`root`是`Root &lt;A&gt;`)。 (2认同)