jpa lazy fetch entities over multiple levels with criteria api

Steven Rudolf picture Steven Rudolf · Jan 9, 2012 · Viewed 9.1k times · Source

I am using JPA2 with it's Criteria API to select my entities from the database. The implementation is OpenJPA on WebSphere Application Server. All my entities are modeled with Fetchtype=Lazy.

I select an entity with some criteria from the database and want to load all nested data from sub-tables at once. If I have a datamodel where table A is joined oneToMany to table B, I can use a Fetch-clause in my criteria query:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<A> cq = cb.createQuery(A.class);
Root<A> root = cq.from(A.class);
Fetch<A,B> fetch = root.fetch(A_.elementsOfB, JoinType.LEFT);

This works fine. I get an element A and all of its elements of B are filled correctly. Now table B has a oneToMany-relationship to table C and I want to load them too. So I add the following statement to my query:

Fetch<B,C> fetch2 = fetch.fetch(B_.elementsOfC, JoinType.LEFT);

But this wont do anything.

Does anybody know how to fetch multi level entities in one query?

Answer

Mikko Maunu picture Mikko Maunu · Jan 15, 2012

It does not work with JPQL and there is no way to make it work in CriteriaQueries either. Specification limits fetched entities to the ones in that are referenced directly from the returned entity:

About fetch join with CriteriaQuery:

An association or attribute referenced by the fetch method must be referenced from an entity or embeddable that is returned as the result of the query.

About fetch join in JPQL:

The association referenced by the right side of the FETCH JOIN clause must be an association or ele ment collection that is referenced from an entity or embeddable that is returned as a result of the query.

Same limitation is also told in OpenJPA documentation.