Cmobilecom JPA 2.0.1 Developer Guide

20. Entity Graph

An entity graph defines the graph of entities to be loaded from persistence for a query. Ideally the fetch types of relations should be LAZY to minimize data loading, and entity graphs should be used to define what exactly to be loaded if necessary.

Entity graphs can either be statically defined in XML or annotations, or dynamically created at runtime. For example,

Named Entity Graphs

A named entity graph can be defined by XML or annotation. For example,
<entity-mappings ...>
    <entity class="Employee" >
        <named-entity-graph name="employee.employeeGraph">
            <named-attribute-node name="name"/>
            <named-attribute-node name="phoneNumbers"/>
 
            <subgraph name="employerSubgraph">
                <named-attribute-node name="name"/>
            </subgraph>
            
            <subclass-subgraph name="fullTimeEmployee" class="FullTimeEmployee">
                <named-attribute-node name="salary"/>
            </subclass-subgraph>
        
            <subclass-subgraph name="partTimeEmployee" class="PartTimeEmployee">
                <named-attribute-node name="hourlyWage"/>
            </subclass-subgraph>
        </named-entity-graph>
    </entity>
</entity-mappings>
The entity graph above can be visualized as:
    Employee(name,phoneNumbers) --> Employer(name)
        \-- FullTimeEmployee(salary)
        \-- PartTimeEmployee(hourlyWage)
Equivalent Annotation:
@NamedEntityGraph(name="employee.employeeGraph",

    attributeNodes = {
        @NamedAttributeNode(value = "name"),
        @NamedAttributeNode(value = "phoneNumbers"),
    },
  
    subgraphs = {
        @NamedSubgraph(name = "employerSubgraph", attributeNodes = {
            @NamedAttributeNode(value = "name"),
        })
    },
	
    subclassSubgraphs = {
        @NamedSubgraph(name="fullTimeEmployee", type=FullTimeEmployee.class,
            attributeNodes = {
                @NamedAttributeNode(value = "salary")}),
        
        @NamedSubgraph(name="partTimeEmployee", type=PartTimeEmployee.class,
            attributeNodes = {
                @NamedAttributeNode(value = "hourlyWage")})
    }
)
Referencing a named entity graph:
    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
    CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);
    Root<Employee> root = criteriaQuery.from(Employee.class);
    criteriaQuery.distinct(true);
    
    TypedQuery<Employee> query = em.createQuery(criteriaQuery);
    EntityGraph<?> entityGraph = em.getEntityGraph("employee.employeeGraph");
    // fetch graph or load graph        
    query.setHint(Constants.FETCH_GRAPH, entityGraph);
    //query.setHint(Constants.LOAD_GRAPH, entityGraph);
    
    List<Employee> employees = query.getResultList();
The hint can be fetch or load graph. Fetch graph instructs JPA provider to fetch exactly what the entity graph defines. However load graph instructs JPA provider to fetch at least what the entity graph defines.

Dynamic Entity Graphs

In addition to static named entity graphs, entity graphs can be dynamically created. For example, create a entity graph equivalent to the named entity graph above:
    EntityGraph<Employee> entityGraph = em.createEntityGraph(Employee.class);
    entityGraph.addAttributeNodes("name", "phoneNumbers", "employer");
    Subgraph<Employer> employerSubgraph = entityGraph.addSubgraph("employer", Employer.class);
    employerSubgraph.addAttributeNodes("name");
    Subgraph<? extends FullTimeEmployee> fullTimeEmployeeSubgraph = entityGraph.addSubclassSubgraph(FullTimeEmployee.class);
    fullTimeEmployeeSubgraph.addAttributeNodes("salary");
    Subgraph<? extends PartTimeEmployee> partTimeEmployeeSubgraph = entityGraph.addSubclassSubgraph(PartTimeEmployee.class);
    partTimeEmployeeSubgraph.addAttributeNodes("hourlyWage");

Fetch Method

For a JPA query retrieving a graph of entities from persistence, there can be multiple SQL queries generated. The main SQL query is to retrieve entities in selection and their relations with explicit or implicit join fetches. One or more SQL queries may be needed to fetch other entities in the graph.
selection(entity) -- attribute(join fetch)  --- attribute(select fetch)
                          |                           |
                     attribute(select fetch)    attribute(select fetch)
                          |                          
                     attribute(join fetch)  --- attribute(join fetch)
                     
The fetch method of a fetch can be join fetch or select fetch. A join fetch will be a join in generated SQL query, and a select fetch will start a new SQL query, which fetches all the data associated with the attribute for all the entities fetched in the previous query for better performance.

By default, the fetch method is join for embedded attributes and singular association attributes, and select for plural attributes.

LockQuery Properties/HintsFrames / No Frames