HHH-11186 - Add examples for all Hibernate annotations
Document @NamedSubgraph
This commit is contained in:
parent
9039291288
commit
6307a47c13
|
@ -408,7 +408,7 @@ See the <<chapters/query/native/Native.adoc#sql-sp-named-query, Using named quer
|
|||
|
||||
The http://docs.oracle.com/javaee/7/api/javax/persistence/NamedSubgraph.html[`@NamedSubgraph`] annotation used to specify a subgraph in an Entity Graph.
|
||||
|
||||
//TODO: Add example
|
||||
See the <<chapters/fetching/Fetching.adoc#fetching-strategies-dynamic-fetching-entity-subgraph, Fetch subgraph>> section for more info.
|
||||
|
||||
[[annotations-jpa-onetomany]]
|
||||
==== `@OneToMany`
|
||||
|
|
|
@ -208,6 +208,40 @@ Entity graphs are the way to override the EAGER fetching associations at runtime
|
|||
With JPQL, if an EAGER association is omitted, Hibernate will issue a secondary select for every association needed to be fetched eagerly.
|
||||
====
|
||||
|
||||
[[fetching-strategies-dynamic-fetching-entity-subgraph]]
|
||||
==== JPA entity subgraphs
|
||||
|
||||
An entity graph specifies which attributes to be fetched, but it limited to a single entity only.
|
||||
To fetch associations from a child entity, you need to use the http://docs.oracle.com/javaee/7/api/javax/persistence/NamedSubgraph.html[`@NamedSubgraph`] annotation.
|
||||
|
||||
If we have a `Project` parent entity which has an `employees` child associations,
|
||||
and we'd like to fetch the `department` for the `Employee` child association.
|
||||
|
||||
[[fetching-strategies-dynamic-fetching-entity-subgraph-mapping-example]]
|
||||
.Fetch graph with a subgraph mapping
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/GraphFetchingTest.java[tags=fetching-strategies-dynamic-fetching-entity-subgraph-mapping-example]
|
||||
----
|
||||
====
|
||||
|
||||
When fetching this entity graph, Hibernate generates the following SQL query:
|
||||
|
||||
[[fetching-strategies-dynamic-fetching-entity-subgraph-example]]
|
||||
.Fetch graph with a subgraph mapping
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/GraphFetchingTest.java[tags=fetching-strategies-dynamic-fetching-entity-subgraph-example]
|
||||
----
|
||||
|
||||
[source, SQL, indent=0]
|
||||
----
|
||||
include::{extrasdir}/fetching-strategies-dynamic-fetching-entity-subgraph-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
[[fetching-strategies-dynamic-fetching-profile]]
|
||||
=== Dynamic fetching via Hibernate profiles
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
select
|
||||
p.id as id1_2_0_, e.id as id1_1_1_, d.id as id1_0_2_,
|
||||
e.accessLevel as accessLe2_1_1_,
|
||||
e.department_id as departme5_1_1_,
|
||||
decrypt( 'AES', '00', e.pswd ) as pswd3_1_1_,
|
||||
e.username as username4_1_1_,
|
||||
p_e.projects_id as projects1_3_0__,
|
||||
p_e.employees_id as employee2_3_0__
|
||||
from
|
||||
Project p
|
||||
inner join
|
||||
Project_Employee p_e
|
||||
on p.id=p_e.projects_id
|
||||
inner join
|
||||
Employee e
|
||||
on p_e.employees_id=e.id
|
||||
inner join
|
||||
Department d
|
||||
on e.department_id=d.id
|
||||
where
|
||||
p.id = ?
|
||||
|
||||
-- binding parameter [1] as [BIGINT] - [1]
|
|
@ -17,10 +17,13 @@ import javax.persistence.ManyToMany;
|
|||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedAttributeNode;
|
||||
import javax.persistence.NamedEntityGraph;
|
||||
import javax.persistence.NamedSubgraph;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.QueryHint;
|
||||
|
||||
import org.hibernate.annotations.ColumnTransformer;
|
||||
import org.hibernate.annotations.NaturalId;
|
||||
import org.hibernate.annotations.QueryHints;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
|
@ -30,7 +33,9 @@ import org.junit.Test;
|
|||
import org.jboss.logging.Logger;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
|
@ -72,6 +77,10 @@ public class GraphFetchingTest extends BaseEntityManagerFunctionalTestCase {
|
|||
employee2.department = department;
|
||||
entityManager.persist( employee2 );
|
||||
|
||||
Project project = new Project();
|
||||
project.id = 1L;
|
||||
project.employees.add( employee1 );
|
||||
entityManager.persist( project );
|
||||
} );
|
||||
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
|
@ -90,6 +99,20 @@ public class GraphFetchingTest extends BaseEntityManagerFunctionalTestCase {
|
|||
assertNotNull(employee);
|
||||
} );
|
||||
|
||||
//tag::fetching-strategies-dynamic-fetching-entity-subgraph-example[]
|
||||
Project project = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
return entityManager.find(
|
||||
Project.class,
|
||||
1L,
|
||||
Collections.singletonMap(
|
||||
"javax.persistence.fetchgraph",
|
||||
entityManager.getEntityGraph( "project.employees" )
|
||||
)
|
||||
);
|
||||
} );
|
||||
//end::fetching-strategies-dynamic-fetching-entity-subgraph-example[]
|
||||
assertEquals(1, project.getEmployees().size());
|
||||
assertEquals( Long.valueOf( 1L ), project.getEmployees().get( 0 ).getDepartment().getId() );
|
||||
}
|
||||
|
||||
@Entity(name = "Department")
|
||||
|
@ -102,6 +125,22 @@ public class GraphFetchingTest extends BaseEntityManagerFunctionalTestCase {
|
|||
private List<Employee> employees = new ArrayList<>();
|
||||
|
||||
//Getters and setters omitted for brevity
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Employee> getEmployees() {
|
||||
return employees;
|
||||
}
|
||||
|
||||
public void setEmployees(List<Employee> employees) {
|
||||
this.employees = employees;
|
||||
}
|
||||
}
|
||||
|
||||
//tag::fetching-strategies-dynamic-fetching-entity-graph-mapping-example[]
|
||||
|
@ -134,10 +173,69 @@ public class GraphFetchingTest extends BaseEntityManagerFunctionalTestCase {
|
|||
private List<Project> projects = new ArrayList<>();
|
||||
|
||||
//Getters and setters omitted for brevity
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public int getAccessLevel() {
|
||||
return accessLevel;
|
||||
}
|
||||
|
||||
public void setAccessLevel(int accessLevel) {
|
||||
this.accessLevel = accessLevel;
|
||||
}
|
||||
|
||||
public Department getDepartment() {
|
||||
return department;
|
||||
}
|
||||
|
||||
public void setDepartment(Department department) {
|
||||
this.department = department;
|
||||
}
|
||||
|
||||
public List<Project> getProjects() {
|
||||
return projects;
|
||||
}
|
||||
|
||||
public void setProjects(List<Project> projects) {
|
||||
this.projects = projects;
|
||||
}
|
||||
}
|
||||
|
||||
//tag::fetching-strategies-dynamic-fetching-entity-subgraph-mapping-example[]
|
||||
@Entity(name = "Project")
|
||||
public class Project {
|
||||
@NamedEntityGraph(name = "project.employees",
|
||||
attributeNodes = @NamedAttributeNode(
|
||||
value = "employees",
|
||||
subgraph = "project.employees.department"
|
||||
),
|
||||
subgraphs = @NamedSubgraph(
|
||||
name = "project.employees.department",
|
||||
attributeNodes = @NamedAttributeNode( "department" )
|
||||
)
|
||||
)
|
||||
public static class Project {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
@ -146,5 +244,24 @@ public class GraphFetchingTest extends BaseEntityManagerFunctionalTestCase {
|
|||
private List<Employee> employees = new ArrayList<>();
|
||||
|
||||
//Getters and setters omitted for brevity
|
||||
//end::fetching-strategies-dynamic-fetching-entity-subgraph-mapping-example[]
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Employee> getEmployees() {
|
||||
return employees;
|
||||
}
|
||||
|
||||
public void setEmployees(List<Employee> employees) {
|
||||
this.employees = employees;
|
||||
}
|
||||
//tag::fetching-strategies-dynamic-fetching-entity-subgraph-mapping-example[]
|
||||
}
|
||||
//end::fetching-strategies-dynamic-fetching-entity-subgraph-mapping-example[]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue