Issue Details (XML | Word | Printable)

Key: JPA_SPEC-27
Type: New Feature New Feature
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Unassigned
Reporter: arjan tijms
Votes: 1
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
jpa-spec

Runtime specification of object graph fetching via path expressions

Created: 24/May/12 08:59 PM   Updated: 18/Jan/13 12:46 AM   Resolved: 18/Jan/13 12:46 AM
Component/s: None
Affects Version/s: None
Fix Version/s: None

Time Tracking:
Not Specified

Tags:
Participants: arjan tijms, ldemichiel and ringerc


 Description  « Hide

In JPA an often recurring problem is how the user tells the persistence provider to which depth an object graph should be fetched.

Lazy- and eager loading is one such method, but these are structural directives. Queries in combination with JOIN FETCH is a more dynamic solution, but having to write variants of a given query for each particular fetch depth and width is non-optimal.

To ease the task of letting the user specify what part of the object graph should be fetched, I would like to propose introducing the concept of simple path expressions. Such path expressions specify which transitive relations from a query root should be eagerly loaded.

For instance:

List<User> users = entityManager.createNamedQuery("User.getAll", User.class)
                                .withDepth("address", "friends.address")
                                .getResultList();

In the above example, both the "address" and the "friends" relation of entity User are being eagerly loaded, and in addition the "address" relation of each element in the "friends" relation is loaded.

The persistence provider should be free to optimize how the intent of the user is realized. E.g. if SQL is generated that uses a JOIN, if separate queries are executed, or perhaps something else entirely.

As an optional part of this proposal, a syntax could be introduced which does let the user specify the most common fetching strategies. E.g. -> for a join and # for a separate query.

Using such syntax, the above code would look like the following:

List<User> users = entityManager.createNamedQuery("User.getAll", User.class)
                                .withDepth("->address", "#friends->address")
                                .getResultList();

In the above example, the persistence provider would try to create a query that joins the tables associated with the User and address, and then a separate query (or queries) that joins the tables associated with friends and address.



arjan tijms added a comment - 24/May/12 09:23 PM

For some more background: I wrote a blog entry that elaborates on the problem and provides a limited ad-hoc solution using the Criteria API at http://jdevelopment.nl/fetching-arbitrary-object-graphs-jpa-2


ringerc added a comment - 25/Jun/12 05:55 AM

Mail sent to the JPA 2.1 Expert Group on the topic here: http://blog.ringerc.id.au/2012/06/mail-to-jpa-21-expert-group-re-fetch.html


ringerc added a comment - 25/Jun/12 06:00 AM

I'm really not a fan of the magic expression approach. There's no way to check it or handle the names in refactoring. I strongly agree that the functionality is needed, but I don't like the proposed API much. Something that can integrate with the dynamic and static JPA metamodels and can survive refactoring would be preferable IMO.

For non-criteria (JPQL) queries, a shorthand fetch control expression might be handy.


ldemichiel added a comment - 18/Jan/13 12:46 AM

Now addressed by use of entity groups to specify fetch plans