Entity graphs can either be statically defined in XML or annotations, or dynamically created at runtime. 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.
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");
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.