Monday 21 December 2015

@NamedEntityGraph in Action

Share & Comment



Table of Content :


Introduction :

The Java Persistence API provides a powerful interface for object-relational mapping. Its usage is straightforward for simple models, but complex models require care and expertise to achieve good performance. JPA loading strategies are a key factor for better performance.

JPA 2.1 introduced a new feature :
Entity Graphs - as a means to address the long standing problem of fetching to different depths in the Entity graph for different use cases. 
JPA 2.1 entity graphs are a better solution to specify the path and boundaries for find operations or queries. The definition of an entity graph is independent of the query and defines which attributes to fetch from the database.
This blog post describes how we can create named entity graph by using JPA Modeler and explains how fetch settings and entity graphs in JPA 2.1 can be used to implement various loading strategies.

Entity Graph:

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
  • Default Entity Graph: implicitly defined in all JPA specs, specifying the fetch setting for each field/property (LAZY/EAGER). 
  • Named Entity Graphs: a new feature in JPA 2.1 allowing the user to define Named Entity Graphs in metadata, via annotations @NamedEntityGraph or deployment descriptor. 
  • Unnamed Entity Graphs (Dynamic): a new feature in JPA 2.1 allowing the user to define Entity Graphs via the createEntityGraph() method of EntityManager API at runtime.
Lets have a look how to define and use an entity graph in JPA Modeler.

Create the JPA Diagram :

  1. Goto File menu > New File > Persistence category.
    Select JPA Diagram
  2. From the Persistence , select JPA Diagram and click Next. 
  3. Type SampleDiagram for the diagram name. 
  4. Type com.jpamodeler.entitygraph for the Package. 
  5. Click Finish. 
When you click Finish, the IDE creates the JPA Diagram and opens the diagram in the designer window.

Create the Entities:

  1. Drag & Drop the Entities  from the Palette window to designer. 
    Palette
  2. Double click on the Entity and rename to Movie.
  3. To create basic attribute, click on the Movie Entity  , then click on the expand   button > basic  property.
  4. To create relation attribute, click on the Movie Entity .
    Add relation property
  5. Now, drag OneToMany  attribute to MovieActor Entity  class.
    Relation property
    Final design

Create the @NamedEntityGrpah :

NamedEntityGraph defines a unique name and a list of attributes ( the attributeNodes ) that have be loaded.
  1. Click on the entity > Properties.
  2. From the properties, select Named Entity Graphs Property.
    Open Entity Graph Panel
  3. Click on the Add button to create new named entity graph.
    Create Entity Grpah
  4. In this panel , you may view entity attributes with check-box in the tree structure. 
    Entity Graph editor
  5. Select the attribute from the tree to add the fields to the entity graph which will be part of attributeNodes element of @NamedEntityGraph with a javax.persistence.NamedAttributeNode annotation and then, type the entity graph name.
    select attributes
  6. In this example, the name of the named entity graph is movieWithActorsAndAwards and include the movieActors field.
  7. Click on the save button to save named entity graph.
    Created Entity Graph

Named 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.
We used the entity graph to define the fetch operation of the Movie entity. If we want to do the same for the MovieActor entity, we can do this with an entity sub graph.
Now, we will edit the entity graph, expand the movieActors attribute and then select the movieActorAwards attribute.
design Sub Entity Graph
The following code snippets shows the definition of a sub graph to load the MovieActorAward of each MovieActor. The defined entity graph will fetch an Movie with all MovieActors and their MovieActorAwards.

View the Entity Graph based on Graph Type :

An entity graph can be used as a fetch or a load graph. 
To check the final view of entity graph based on the graph type on the View button, after selection of attribute.

  • If a fetch graph is used, only the attributes specified by the entity graph will be treated as FetchType.EAGER and all other attributes will be lazy. 
    Fetch Graph
  • If a load graph is used, all attributes that are not specified by the entity graph will keep their default fetch type.
    Load Graph
Entity graphs have attributes that correspond to the fields that will be eagerly fetched during a find or query operation. The primary key and version fields of the entity class are always fetched and do not need to be explicitly added to an entity graph.

Generate the entity classes :

  1. Right click on the diagram > Generate Source Code.
    Generate Source Code
  2. Click on the Movie entity class to view source code. 

Obtaining EntityGraph Instances from Named Entity Graphs:

Use the EntityManager.getEntityGraph method, passing in the named entity graph name, to obtain EntityGraph instances:
EntityGraph eg = em.getEntityGraph("movieWithActorsAndAwards");
You can use an entity graph with the EntityManager.find method or as part of a JPQL or Criteria API query by specifying the entity graph as a hint to the operation or query.

Using Entity Graphs in Query Operations:

Now that we have defined the entity graph, we can use it in a query. To specify entity graphs for both typed and untyped queries, call the setHint method on the query object and specify either javax.persistence.loadgraph or javax.persistence.fetchgraph as the property name and an EntityGraph instance as the value.
The following code snippet shows how to use a named entity graph as a fetch graph in a find statement :

In this example, the movieWithActorsAndAwards is used for the Movie.findAll named query and we provide this graph as a hint to the entity manager, to fetch the movies and all their actors in one query.

Download Source Code : 

Github - Named Entity Graph

Conclusion:

The Entity Graph overrides the default loading strategy, and provides flexibility of loading the association & attributes of an Entity and helps to improve the performance of application. The usage and definition of the entity graph does not depends on query and we can fetch a graph of multiple entities with only one select query, so the main drawbacks of the JPA 2.0 are solved.
The Above example shows a very simple entity graph and you will probably be using more complex graphs in a real application which may have more annotations than actual code and that would make the code harder to read, so the JPA Modeler assist the developer to design & manage the entity graph and generate & reverse-engineering the annotation by modeler.





Tags:

Author -

Shiwani is a software engineer with a passion for learning. She is an enthusiast of netbeans and new technologies and developer of JPA Modeler.

0 comments:

 
Copyright © JPA Modeler | Designed by Templateism.com