JPA 2.1 enables us to use named entity graphs that describe what part of entity graph should be loaded. Instead of using one default graph described by FetchType attributes on relation fields and basic fields (in this case code weaving is required) we can now define a few named graphs. Should I mention Fetch Joins used in JPQL and Criteria API ? Well, I don’t find use cases for these equal:

  • With Fetch Joins you have to duplicate query or use tricks like storing core part of query in one field and then concatenate case specific part. On the other hand you can do advanced filtering, grouping and ordering.
  • With Criteria API you can do the same but you can extract common query part to some method
  • Both with Criteria API and JPQL in order to cache results in L2 Cache you must enable query cache

The use cases for named entity graphs are the ones where we do not need advanced filtering or grouping and we do not want to use query cache. Entities fetched with entity graph are cached in L1 cache if EntityManager cache is used. So how can we use named entity graphs?

Let’s say we are given following tables mapped to entities:

entities

On Customer entity we can specify named entity graphs:

In code snippet above there are two named entity graphs:

  • CRT.CUSTOMERS_WITH_PHONES – this one fetched customer data and phones for the customer
  • CRT.CUSTOMER_DATA – this one fetches only basic customer data

Those graphs are simple, this makes it even easier to show some properties. Every entity graphs is a set of:

  • attributeNodes – defined fields/properties that are to be fetched, they can reference subgraphs. Here we use NamedAttributeNode annotation which  value is field/property name that is to be fetched
  • subgraphs – define graphs for related entities, element collections and embedded classes
  • subclassGraphs – defined subgraph for subclasses

@NamedEntityGraphs defines also the  includeAllAttributes attribute that tells jpa provider do load all entity fields/properties, subgraphs still have to be specified.

Now that we have graphs defined We can use this graphs in two ways:

  • as fetch graphs – in this case if an attribute is not specified in named entity graph (including subgraphs) it is treated like it was lazy loaded
  • as load graphs – in this case default fetch type is used to attributes that are not specified in named entity graph (or one of subgraphs)

Let’s test it !

Hibernate JPA provider test:

We specify fetch graph to be used by setting a hint in query instance. As a hint value we specify named entity graph retrieved from EntityManager –  newEntityManager.getEntityGraph(Customer.CUSTOMER_DATA). Orders and phones are not fetched. Note that we use “javax.persistence.fetchgraph” hint – so the fields/properties not specified in graph will be treated as lazy loaded.

Let’s test graph with phones:

Here we using fetch graph but this time named entity graph included phones and they are loaded.

How about load graph ?

In test above named entity graph does not specify phones or orders, but load graph hint is used so default fetch type applies. And both order and phones are not fetched.

How about finder method? Let’s see:

Named entity graphs work in same way. Additionally with query logging enabled we can se that query for customer will be done once.

If we would like to use named entity graphs with O2O relations or basic fields/properties that we will be disappointed:

Both Hibernate and Eclipselink will fetch additional fields in case of One2One mapping and basic properties, and to this according to JPA Spec.

I think I’d rather stick to Fetch Joins and criteria API.

Code with examples will be  are available on GitHub

Cheers !