When an object is retrieved from the datastore by JPA typically not all fields are retrieved immediately. This is because for efficiency purposes only particular field types are retrieved in the initial access of the object, and then any other objects are retrieved when accessed (lazy loading). The group of fields that are loaded is called an entity graph. There are 3 types of "entity graphs" to consider
JPA provides an initial entity graph, comprising the fields that will be retrieved when an object is retrieved if the user does nothing to define the required behaviour. You define this "default" by setting the fetch attribute in metadata for each field/property.
You can predefine Named Entity Graphs in metadata which can then be used at runtime when retrieving objects from the datastore (via find/query). For example, if we have the following class
class MyClass { String name; HashSet coll; MyOtherClass other; }
and we want to have the option of the other field loaded whenever we load objects of this class, we define our annotations as
@Entity @NamedEntityGraph(name="includeOther", attributeNodes={@NamedAttributeNode("other")}) public class MyClass { ... }
So we have defined an EntityGraph called "includeOther" that just includes the field with name other. We can retrieve this and then use it in our persistence code, as follows
EntityGraph includeOtherGraph = em.getEntityGraph("includeOther"); Properties props = new Properties(); props.put("javax.persistence.loadgraph", includeOtherGraph); MyClass myObj = em.find(MyClass.class, id, props);
Here we have made use of the EntityManager.find method and provided the property javax.persistence.loadgraph to be our EntityGraph. This means that it will fetch all fields in the default EntityGraph, plus all fields in the includeOther EntityGraph. If we had provided the property javax.persistence.fetchgraph set to our EntityGraph it would have fetched just the fields defined in that EntityGraph.
Note that you can also make use of EntityGraphs when using the JPA Query API, specifying the same properties above but as query hints.
You can define Entity Graphs at runtime, programmatically. For example, if we have the following class
class MyClass { String name; HashSet coll; MyOtherClass other; }
and we want to have the option of the other field loaded whenever we load objects of this class, we do the following
EntityGraph includeOtherGraph = em.createEntityGraph(MyClass.class); includeOtherGraph.addAttributeNodes("other");
So we have defined an EntityGraph that just includes the field with name other. We can then use this at runtime in our persistence code, as follows
Properties props = new Properties(); props.put("javax.persistence.loadgraph", includeOtherGraph); MyClass myObj = em.find(MyClass.class, id, props);
Here we have made use of the EntityManager.find method and provided the property javax.persistence.loadgraph to be our EntityGraph. This means that it will fetch all fields in the default EntityGraph, plus all fields in this EntityGraph. If we had provided the property javax.persistence.fetchgraph set to our EntityGraph it would have fetched just the fields defined in that EntityGraph.
Note that you can also make use of EntityGraphs when using the JPA Query API, specifying the same properties above but as query hints.