JPA Entity Graphs: How to Define and Use a @NamedEntityGraph

Lazy loading is often an issue with JPA. You have to define at the entity if you want to use FetchType.LAZY (default) or FetchType.EAGER to load the relation and this mode is always used. FetchType.EAGER is only used if we want to always load the relation. FetchType.LAZY is used in almost all of the cases to get a well performing and scalable application.But this is not without drawbacks. If you have to use an element of the relation, you need to make sure, that the relation gets initialized within the transaction that load the entity from the database. This can be done by using a specific query that reads the entity and the required relations from the database. But this will result in use case specific queries. Another option is to access the relation within your business code which will result in an additional query for each relation. Both approaches are far from perfect.

JPA 2.1 entity graphs are a better solution for it. The definition of an entity graph is independent of the query and defines which attributes to fetch from the database. An entity graph can be used as a fetch or a load graph. If a fetch graph is used, only the attributes specified by the entity graph will be treated as FetchType.EAGER. All other attributes will be lazy. If a load graph is used, all attributes that are not specified by the entity graph will keep their default fetch type.

Let’s have a look how to define and use an entity graph.

The example entities

For this example, we will use an order with a list of items and each item has a product. All relations are lazy.

Named entity graph

The definition of a named entity graph is done by the @NamedEntityGraph annotation at the entity. It defines a unique name and a list of attributes (the attributeNodes) that shall be loaded.The following example shows the definition of the entity graph graph.Order.items which will load the list of OrderItem of an Order.

Now that we have defined the entity graph, we can use it in a query. Therefore we need to create a Map with query hints and set it as an additional parameter on a find or query method call.
The following code snippet shows how to use a named entity graph as a fetch graph in a find statement.

Named sub graph

We used the entity graph to define the fetch operation of the Order entity. If we want to do the same for the OrderItem entity, we can do this with an entity sub graph. The definition of a named sub graph is similar to the definition of an named entity graph and can be referenced as an attributeNode.The following code snippets shows the definition of a sub graph to load the Product of each OrderItem. The defined entity graph will fetch an Order with all OrderItems and their Products.

What’s happening inside?

OK, from a development point of view entity graphs are great. They are easy to use and we do not need to write additional code to avoid lazy loading issues. But what is happening inside? How many queries are send to the database? Lets have a look at the hibernate debug log.

The log shows that only one query is created. Hibernate uses the entity graph to create a load plan with all 3 entities (Order, OrderItem and Product) and load them with one query.

Conclusion

We defined an entity graph that tells the entity manager to fetch a graph of 3 related entities from the database (Order, OrderItem and Product). The definition and usage of the entity graph is query independent and results in only one select statement. So the main drawbacks of the JPA 2.0 approaches (mentioned in the beginning) are solved.

From my point of view, the new entity graph feature is really great and can be a good way to solve lazy loading issues. What do you think about it? Please leave me a comment.

And if you want to learn more about the new JPA 2.1 features, have a look at my other articles:

Improve Your Hibernate Skills At An In-Person Workshop

Implement Your Persistence Layer with Ease

Learn More About Hibernate

Need Some Help with Your Project?

Reader Interactions

Comments

Wow, I am surprised no one has commented on this article. This is one of the coolest features I have seen in JPA, it does solve a huge problem that many JPA developers have. In many cases developers haven’t even been implementing the Use Case @NamedQueries approach (Which I believed was a HUGE MUST DO before) I have seen way too many applications crumble under performance because they took a lazy approach and N+1 or eager fetch everything.

I have a question: What are the benefits of use Entity Graph instead of fetch join approach? If I am right, If we need to load different relations we need to define different entity graphs, the same disadvantage that in the fetch join approach.

in my experience, the query is most often more complicated than the EntityGraph. So, it can be useful to reuse the query.
If that’s not the case or the query is specific to the use case, you can also use a JOIN FETCH clause.

IMHO, this feature is equivalent to writing NamedQueries, just with more awkward syntax. You can specify the join fetches in your NamedQuery to ensure only one statement is sent to the DB. You mention that the query approach results in ‘use case specific queries’ but I don’t see how the EntityGraph is anything more than a ‘use case specific graph’ following that rationale.

I just read this article and looking forward to implement in one of the upcoming functionality in my project and see how it works.. But by going through this article I feel that this should be helpful. Will revert back if I am done with implementation successfully.
Cheers

Hello, is it possible to use this feature for changing the default Eager loading of a single attribute ? For example if I have an Entity that has a JsonAttribute (custom user type) that is mapped to a varchar or json column in the DB and in some cases I need to override the Eager loading and let hibernate Lazy load this property ? Thanks!

yes, subgraphs can also use subgraphs so that you can define a huge tree of entities that get loaded from the database.
But make sure to load only the relationships you really need and keep in mind that the unnecessary loading of attributes also creates an overhead. POJO projections are most often the better approach if you need a few attributes out of huge tree of entities.

Is it possible to use NamedEntityGraph without the primary key/id field ? In the above example, say I have an order number which is unique but still not the id field . Will I be able to load an entity graph based on the order number ?

I don’t understand your question. Are you asking about the query with which you want to use the graph?
You can use entity graphs with all JPQL and Criteria queries. You don’t have to select an entity by its primary key.

that’s right. EntityGraphs provide the advantage that they’re independent of the query. So, you can use the same query with or without the FetchGraph.
If that’s a real advantage depends on your query and use cases, of course. 😉

Hello,
Thanks for the great article and great explanation of the problem.
I see that this feature of JPA 2.1 is great for solving the N+1 Problem. However, my doubts are that, in a real world application that would probably scale and have at least dozens of thousands rows per table, using Entity Graphs can be really painful for the Database, since the numerous joins.
What are your thoughts on this ?

Hi,
That depends on your table model and the conditions in your WHERE clause. In some situations, joining multiple associations creates huge result sets which create new problems.
As so often, you need to select the best option for your specific use case.
Regards,
Thorben

Is it possible for “subgraph” to refer to another NamedEntityGraph, instead of defining it locally? Let’s say if same “subgraph” is required in multiple entities then have to duplicate it everywhere. Can we define one namedEntityGraph and use it as “subGraph” inother places?