按条件 api 的集合字段的嵌套 属性 进行搜索
Search by nested property of collection field with criteria api
我正在尝试查找所有具有一些嵌套元素的实体,并且嵌套元素具有元素集合,我需要通过 属性 这些集合来找到它。
会是这样的
class A{
private B b;
}
class B{
private Collection<C> cCol;
}
class C{
private String name;
}
所以我想获取所有具有 B 元素的 A 元素,这些元素具有名称与给定参数匹配的 C。
不确定如何使用 JPA Critieria API。我知道 JPQL 中有谓词或 MEMEBER OF,但我需要按集合中元素的 属性 进行搜索,而不是集合成员。
尝试了 root.get(a.b.c.name)
以及 root.fetch(a.b)
或 root.fetch(b.c)
之类的方法,但总是以一些关于非法 api 用法的异常告终
以下应该有效
root.get("a").get("b").get("name")
见
I want to get all A elements that have B elements that have a C which name matches given parameter.
在尝试导航条件 API 时,我发现首先编写 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<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();
Java 变量的名称与 JPQL 中的相同,例如Join<A, B> b
对应 JPQL FROM a.b b
.
我使用
成功了
root.**join**("a").get("b").get("name"):
因为是合集。
我是通过这样的连接实现的:
builder = entityManager.getCriteriaBuilder();
CriteriaQuery<A> query = builder.createQuery(A.class);
Root<A> root = query.from(A.class);
root.join("b").join("c").get("name");
我正在尝试查找所有具有一些嵌套元素的实体,并且嵌套元素具有元素集合,我需要通过 属性 这些集合来找到它。
会是这样的
class A{
private B b;
}
class B{
private Collection<C> cCol;
}
class C{
private String name;
}
所以我想获取所有具有 B 元素的 A 元素,这些元素具有名称与给定参数匹配的 C。
不确定如何使用 JPA Critieria API。我知道 JPQL 中有谓词或 MEMEBER OF,但我需要按集合中元素的 属性 进行搜索,而不是集合成员。
尝试了 root.get(a.b.c.name)
以及 root.fetch(a.b)
或 root.fetch(b.c)
之类的方法,但总是以一些关于非法 api 用法的异常告终
以下应该有效
root.get("a").get("b").get("name")
见
I want to get all A elements that have B elements that have a C which name matches given parameter.
在尝试导航条件 API 时,我发现首先编写 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<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();
Java 变量的名称与 JPQL 中的相同,例如Join<A, B> b
对应 JPQL FROM a.b b
.
我使用
成功了root.**join**("a").get("b").get("name"):
因为是合集。
我是通过这样的连接实现的:
builder = entityManager.getCriteriaBuilder();
CriteriaQuery<A> query = builder.createQuery(A.class);
Root<A> root = query.from(A.class);
root.join("b").join("c").get("name");