I'm trying to find all entities that have some nested elements and nested elemens have collections of elements, and I need to find it by property of those collections.
It would be something like this
class A{
private B b;
}
class B{
private Collection<C> cCol;
}
class C{
private String name;
}
So I want to get all A elements that have B elements that have a C which name matches given parameter.
Not sure how to do it with JPA Critieria API. I know there is in predicate, or MEMEBER OF in JPQL but I need to search by property of element in collection, not a collection member.
Tried things like root.get(a.b.c.name)
and also with root.fetch(a.b)
or root.fetch(b.c)
but always ended up with some exceptions about illegal api usage
I want to get all A elements that have B elements that have a C which name matches given parameter.
When trying to navigate the criteria API I find it immensely helpful to write the JPQL query first. Here it is:
SELECT a
FROM A a
WHERE EXISTS(
SELECT c FROM a.b b JOIN b.cCol c WHERE c.name = 'condition'
)
Now the criteria API becomes clearer (if that is possible at all):
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();
The names of the Java variables are the same as in the JPQL, e.g. Join<A, B> b
corresponds to the JPQL FROM a.b b
.
The below should work
root.get("a").get("b").get("name")
See
How to create specification using JpaSpecificationExecutor by combining tables?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With