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.
|
||||
====
|
||||
|
||||
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]]
|
||||
=== 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:
|
||||
|
||||
.Predefined column lengths
|
||||
[%autowidth.stretch]
|
||||
[cols="10,12,~"]
|
||||
|===
|
||||
| Constant | Value | Description
|
||||
|
||||
|
|
Loading…
Reference in New Issue