Featured Image with Sidebar

JPA Entity Graphs: How to Dynamically Define and Use an EntityGraph

By Thorben Janssen

Criteria API, Jpql, Query

This is my second post on Entity Graphs, one of the features introduced with JPA 2.1. The first post described the usage of named entity graphs. These can be used to define a graph of entities and/or attributes at compile time that shall be fetched with a find or query method. Dynamic entity graphs do to the same but in a dynamic way. This means you can use the EntityGraph API to define your entity graph at runtime.
If you have missed the first post and want to read how to define a named entity graph or how lazy loading issues were solved with JPA 2.0, check this post: JPA 2.1 Entity Graph – Part 1: Named entity graphs

The example entities

We will use the same example as in the previous post. So you can skip this paragraph if you have read the other one.
We will use 3 entities. These are Order, OrderItem and Product. An Order might include multiple OrderItems and each OrderItem belongs to one Product. The FetchType of all these relations it FetchType.LAZY. So the entity manager will not fetch them from the database by default and initialize them with a proxy instead.

The Order entity:

The OrderItem entity:

The Product entity:

Dynamic entity graph

So lets define a dynamic entity graph. We will do the same as in the first post and define a simple entity graph that tells the entity manager to fetch an Order with all associated OrderItems. Therefore we use the createEntityGraph(Class rootType) method of the entity manager to create an entity graph for the Order entity. In the next step, we create a list of all attributes of the Order entity that shall be fetched with this entity graph. We only need to add the attribute items, because we will use this entity graph as a loadgraph and all other attributes are eager by default.
If we would use this entity graph as a fetchgraph, we would need to add all attributes to the list that should be fetched from the database.

OK, dynamically defining which attributes of an entity shall be fetched from the database is nice. But what if we need a graph of entities? Like fetching an Order with all its OrderItems and their Product?
This can be done with a sub graph. A sub graph is basically an entity graph that is embedded into another entity graph or entity sub graph. The definition of a sub graph is similar to the definition of an entity graph. To create and embed the sub graph into an entity graph, we need to call the addSubgraph(String attributeName) method on an EntityGraph object. This will create a sub graph for the attribute with the given name. In the next step, we need to define the list of attributes that shall be fetched with this sub graph.
The following snippet shows the definition of an entity graph with an entity sub graph which tell the entity manager to fetch an Order with its OrderItems and their Product.

What’s happening inside?

As in the previous post, we want to have a look at the hibernate log and find out what hibernate is doing. As we can see, the result of a dynamic entity graph is the same as of a named entity graph. It creates a load plan and one select statement with all 3 entities.

Conclusion

After defining a named entity graph in the first post, we now used the EntityGraph API to define an dynamic entity graph. Using this entity graph, we can fetch a graph of multiple entities with only one query from the database. This can be used to solve LazyInitializationException and to improve the performance applications.

What do you think about (dynamic) entity graphs? From my point of view this is a very useful extension compared to JPA 2.0. Especially the dynamic entity graphs are useful to define your fetch strategy based on runtime information like method parameters.

If you enjoyed reading this article and like to learn more about other Java EE7 features, make sure to subscribe to my RSS feed or follow me on twitter and google+.

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

Specification

About the author

Thorben is an independent consultant, international speaker, and trainer specialized in solving Java persistence problems with JPA and Hibernate.
He is also the author of Amazon’s bestselling book Hibernate Tips - More than 70 solutions to common Hibernate problems.

Books and Courses

Coaching and Consulting

Leave a Repl​​​​​y

Your email address will not be published. Required fields are marked

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  1. Has anyone written a utility to generate the graph and map in one function by passing in the Classes of objects that are to be graphed?

    I like this implementation, but if you have two or more levels of sub entities then the graph creation can get very ugly.

    1. I’m not aware of such an implementation.
      How would you handle the situation that there are 2 associations with the same type?

  2. Hi Thorben ,

    Entity Graph is a great feature introduced in JPA . I got solution for most of my problems where i need to fetch large data set with associations at once . But is it possible create dynamic entity graphs with multi level depth and fetch data ?

    For example Instructor —ManyToMany–> Students —OneToMany-> Vehicle –OneToOne–> VehicleComapny

    Will be really helpful if you can give me a code example to do this !

    Regards ,
    Vaneet Kataria

    1. Hi Vaneet,

      The addSubgraph method of the EntityGraph and Subgraph interfaces return a new Subgraph object. That enables you to create such a graph.

      EntityGraph graph = this.em.createEntityGraph(Order.class);
      Subgraph itemGraph = graph.addSubgraph(“items”);
      itemGraph.addAttributeNodes(“product”);

      Please be aware that huge entity graphs might cause performance problems because your query result gets huge.
      And you should model your to-many association as a Set to avoid the MultipleBagFetchException (see Hibernate Tips: How to avoid Hibernate’s MultipleBagFetchException)

      Regards,
      Thorben

  3. Hi Thorben,
    I am using the JPA 2.1 . I am debugging the code and found that It’s not working. Whenever I expand a object in debug a query got fire. But my expectation is Query should not fire in the . It should be join fetch for Eager.
    Please correct me if I missed or wrong anywhere.

    Thanks,
    Amit Yadav

    1. It sounds like your EntityGraph wasn’t used or didn’t work correctly. Did you provide it as a hint to your query?

  4. How can I use a dynamic entity graph in conjunction with a CrudRepository or similar? I can get a handle on the EntityManager, but that doesn’t help because I’m not calling em.find, so I can’t give it the hints!

    1. I’m not sure if I understand your question. Do you want to use the EntityGraph with a query?

      You can do that by calling the setHint method on the Query or TypedQuery interface.

      TypedQuery q = em.createQuery(“SELECT a FROM Author a WHERE a.id = 1”, Author.class);
      q.setHint(“javax.persistence.fetchgraph”, graph);
      Author a = q.getSingleResult();

      Regards,
      Thorben

  5. In this graph:
    @NamedEntityGraph(name = “graph.Order.items”,
    attributeNodes = @NamedAttributeNode(value = “items”, subgraph = “items”),
    subgraphs = @NamedSubgraph(name = “items”, attributeNodes = @NamedAttributeNode(“product”)))

    items and its products are already defined to be eager.. right?

    Why when you decide to use this graph, you have to specify AGAIN what need/want to be fetched:
    Subgraph itemGraph = graph.addSubgraph(“items”);
    itemGraph.addAttributeNodes(“product”);

    Makes no sense

    1. These are 2 different ways to define the same graph.

      The @NamedEntityGraph annotation provides an annotation-based approach to define the graph. This graph can’t be changed at runtime
      The Graph API allows you to dynamically create the graph at runtime.

      In the end, you can use both approaches to create the same graph. That’s what I did in this article.

  6. We have a pretty large class hierarchy (table per class hierarchy using a discriminator column). When I run a query for a certain subclass, all the ManyToOne associations are being eagerly fetched ( at least 25 sql queries to various tables). I’m only looking for few properties that are spread across the class hierarchy. 2 properties in the parent class, 3 properties in a subclass. When I create an entity graph and try to fetch using the javax.persistence.fetchgraph property, I’m seeing the same number of sql queries. I’m trying to understand if by using the entityGraph approach shouldn’t I see fewer number of queries .. or what problem does this solve? Thanks

  7. Hello Thorben,
    I really like this artikle. But as my company is still unsing JPA 2.0 and I am new in this field: Is everything also possible with JPA 2.0?

      1. This might be true for hibernate-specific (“vendor-specific”) things, but how about for JPA? The JPA is a vendor-independent approach to overcome the implications and limitations you had with when you implement against a specific implementation (like hibernate is). Now we have the javax.persistence.* packages which form the JPA (independent from DBMS and persistence implementation).

        Surely you already know the difference: Hibernate (vendor-specific) != JPA (vendor-independent). So let’s encourage people of moving away from a specific vendor and lead them towards generic JPA.

        PS: Sorry when I may sound not polite, it was not intended (non-native English writer).

  8. No, I have not seen it in a “real” project so far. But that will change as soon as critical applications switch to JEE7 application servers.

    Having hundreds of these annotations might get a little messy 😉
    But it would be similar with predefined SQL statements. You have to put the predefined stuff somewhere in the end.
    The only alternative would be to create the statement at runtime, based on the user input. And with JPA 2.1 you could even create a dynamic entity graph for the query 😉
    But creating everything at runtime has also several drawbacks…

    Independent of your approach to define a database query, structuring a hughe application is not an easy job. And I don't think, that there is a one size fits all approach. You always need to find the best solution for your current application.

    Regards,
    Thorben

  9. I'm really very curious where this whole Annotatiomania™ leads us. Once we declare something like a named entity graph with declarative tools like annotations, I really start wondering why we have stopped writing SQL.

    I understand that this whole set of features will go through a variety of caches in Hibernate and leverage the whole platform. But the sheer complexity of a project that yields hundreds of such entity graphs makes me think if querying shouldn't better be done with the optimal query language for RDBMS.

    Have you already seen these JEE7 things in the wild?

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}