document EntityGraphs
This commit is contained in:
parent
56ffbc104c
commit
8ddbb033cd
|
@ -337,6 +337,72 @@ We're getting a bit ahead of ourselves here, but let's quickly mention the gener
|
||||||
Instead, fetch all the data you'll need upfront at the beginning of a unit of work, using one of the techniques described in <<association-fetching>>, usually, using _join fetch_ in HQL.
|
Instead, fetch all the data you'll need upfront at the beginning of a unit of work, using one of the techniques described in <<association-fetching>>, usually, using _join fetch_ in HQL.
|
||||||
====
|
====
|
||||||
|
|
||||||
|
It's clear we need a way to request that an association be _eagerly_ fetched using a database `join`.
|
||||||
|
One way to do that is by passing an `EntityGraph` to `find()`.
|
||||||
|
|
||||||
|
[[entity-graph]]
|
||||||
|
=== Entity graphs and eager fetching
|
||||||
|
|
||||||
|
When an association is mapped `fetch=LAZY`, it won't, by default, be fetched when we call the `find()` method.
|
||||||
|
We may request that an association be fetched eagerly (immediately) by passing an `EntityGraph` to `find()`.
|
||||||
|
|
||||||
|
The JPA-standard API for this is a bit unwieldy:
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
var graph = entityManager.createEntityGraph(Book.class);
|
||||||
|
graph.addSubgraph(Book_.publisher);
|
||||||
|
entityManager.find(Book.class, bookId, Map.of(SpecHints.HINT_SPEC_FETCH_GRAPH, graph));
|
||||||
|
----
|
||||||
|
|
||||||
|
This is untypesafe and a bit verbose.
|
||||||
|
Hibernate has a better way:
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
var graph = session.createEntityGraph(Book.class);
|
||||||
|
graph.addSubgraph(Book_.publisher);
|
||||||
|
session.byId(Book.class).fetching(graph).load(bookId);
|
||||||
|
----
|
||||||
|
|
||||||
|
This code adds a `left outer join` to our SQL query, fetching the associated `Publisher` along with the `Book`.
|
||||||
|
|
||||||
|
We may even attach additional nodes to our `EntityGraph`:
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
var graph = session.createEntityGraph(Book.class);
|
||||||
|
graph.addSubgraph(Book_.publisher);
|
||||||
|
graph.addPluralSubgraph(Book_.authors).addSubgraph(Author_.person);
|
||||||
|
session.byId(Book.class).fetching(graph).load(bookId);
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
This results in a SQL query with _four_ ``left outer join``s.
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
In the code examples above, we're making use of the JPA static metamodel.
|
||||||
|
The classes `Book_` and `Author_` are generated by the annotation processor we have in our <<hello-hibernate,gradle build>>, one of the <<optional-dependencies,optional dependencies>> of Hibernate.
|
||||||
|
They let us refer to attributes of our model in a completely type-safe way.
|
||||||
|
We'll use them again, below, when we talk about <<criteria-queries>>.
|
||||||
|
====
|
||||||
|
|
||||||
|
JPA specifies that any given `EntityGraph` may be interpreted in two different ways.
|
||||||
|
|
||||||
|
- A _fetch graph_ specifies exactly the associations that should be eagerly loaded.
|
||||||
|
Any association not belonging to the entity graph is proxied and loaded lazily only if required.
|
||||||
|
- A _load graph_ specifies that the associations in the entity graph are to be fetched in addition to the associations mapped `fetch=EAGER`.
|
||||||
|
|
||||||
|
You're right, the names make no sense.
|
||||||
|
But don't worry, if you take our advice, and map your associations `fetch=LAZY`, there's no difference between a "fetch" graph and a "load" graph, so the names don't matter.
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
JPA even specifies a way to define named entity graphs using annotations.
|
||||||
|
But the annotation-based API is so verbose that it's just not worth using.
|
||||||
|
====
|
||||||
|
|
||||||
[[flush]]
|
[[flush]]
|
||||||
=== Flushing the session
|
=== Flushing the session
|
||||||
|
|
||||||
|
|
|
@ -559,7 +559,7 @@ So we don't usually need to explicitly specify that a column should be of type `
|
||||||
The constant values defined in the class `org.hibernate.Length` are very helpful here:
|
The constant values defined in the class `org.hibernate.Length` are very helpful here:
|
||||||
|
|
||||||
.Predefined column lengths
|
.Predefined column lengths
|
||||||
[%autowidth.stretch]
|
[cols="10,12,~"]
|
||||||
|===
|
|===
|
||||||
| Constant | Value | Description
|
| Constant | Value | Description
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue