update the docs with new @FetchProfileOverride
and the "default" profile
This commit is contained in:
parent
66d67795a3
commit
2e502215d5
|
@ -721,11 +721,11 @@ class Book {
|
|||
...
|
||||
|
||||
@ManyToOne(fetch = LAZY)
|
||||
@Fetch(profile = "EagerBook", value = JOIN)
|
||||
@FetchProfileOverride(profile = "EagerBook", mode = JOIN)
|
||||
Publisher publisher;
|
||||
|
||||
@ManyToMany
|
||||
@Fetch(profile = "EagerBook", value = JOIN)
|
||||
@FetchProfileOverride(profile = "EagerBook", mode = JOIN)
|
||||
Set<Author> authors;
|
||||
|
||||
...
|
||||
|
@ -738,7 +738,7 @@ class Author {
|
|||
...
|
||||
|
||||
@OneToOne
|
||||
@Fetch(profile = "EagerBook", value = JOIN)
|
||||
@FetchProfileOverride(profile = "EagerBook", mode = JOIN)
|
||||
Person person;
|
||||
|
||||
...
|
||||
|
@ -756,12 +756,12 @@ class Book {
|
|||
...
|
||||
|
||||
@OneToOne
|
||||
@Fetch(profile = "EagerBook", value = JOIN)
|
||||
@FetchProfileOverride(profile = "EagerBook", mode = JOIN)
|
||||
Person person;
|
||||
|
||||
@ManyToMany
|
||||
@Fetch(profile = "EagerBook", value = JOIN)
|
||||
@Fetch(profile = "BookWithAuthorsBySubselect", value = SUBSELECT)
|
||||
@FetchProfileOverride(profile = "EagerBook", mode = JOIN)
|
||||
@FetchProfileOverride(profile = "BookWithAuthorsBySubselect", mode = SUBSELECT)
|
||||
Set<Author> authors;
|
||||
|
||||
...
|
||||
|
@ -783,7 +783,7 @@ But the format of this annotation is _even worse_ than the format of the `@Fetch
|
|||
|
||||
| `@FetchProfile` | Declares a named fetch profile, optionally including a list of ``@FetchOverride``s
|
||||
| `@FetchProfile.FetchOverride` | Declares a fetch strategy override as part of the `@FetchProfile` declaration
|
||||
| `@Fetch` | Specifies the fetch strategy for the annotated association, in a given fetch profile
|
||||
| `@FetchProfileOverride` | Specifies the fetch strategy for the annotated association, in a given fetch profile
|
||||
|===
|
||||
|
||||
A fetch profile must be explicitly enabled for a given session:
|
||||
|
@ -806,3 +806,18 @@ But Hibernate offers alternatives that we think are more compelling most of the
|
|||
|
||||
The one and only advantage unique to fetch profiles is that they let us very selectively request subselect fetching.
|
||||
We can't do that with entity graphs, and we can't do it with HQL.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
There's a special built-in fetch profile named `org.hibernate.defaultProfile` which is defined as the profile with `@FetchProfileOverride(mode=JOIN)` applied to every eager `@ManyToOne` or `@OneToOne` association.
|
||||
If you enable this profile:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
session.enableFetchProfile("org.hibernate.defaultProfile");
|
||||
----
|
||||
|
||||
Then ``outer join``s for such associations will _automatically_ be added to every HQL or criteria query.
|
||||
This is nice if you can't be bothered typing out those ``join fetch``es explicitly.
|
||||
And in principle it even helps partially mitigate the <<many-to-one,problem>> of JPA having specified the wrong default for the `fetch` member of `@ManyToOne`.
|
||||
====
|
||||
|
|
|
@ -130,7 +130,6 @@ Of these, you should almost always use outer join fetching.
|
|||
=== Batch fetching and subselect fetching
|
||||
|
||||
Both batch fetching and subselect fetching are disabled by default, but we may enable one or the other globally using properties.
|
||||
Later, we'll see how we can use <<fetch-profiles,fetch profiles>> to do this more selectively.
|
||||
|
||||
.Configuration settings to enable batch and subselect fetching
|
||||
[cols="35,~"]
|
||||
|
@ -141,13 +140,13 @@ Later, we'll see how we can use <<fetch-profiles,fetch profiles>> to do this mor
|
|||
| `hibernate.use_subselect_fetch` | `true` to enable subselect fetching
|
||||
|===
|
||||
|
||||
That's all there is to it.
|
||||
Too easy, right?
|
||||
Alternatively, we can enable one or the other in a given session:
|
||||
|
||||
Sadly, that's not the end of the story.
|
||||
While batch fetching might _mitigate_ problems involving N+1 selects, it won't solve them.
|
||||
The truly correct solution is to fetch associations using joins.
|
||||
Batch fetching (or subselect fetching) can only be the _best_ solution in rare cases where outer join fetching would result in a cartesian product and a huge result set.
|
||||
[source,java]
|
||||
----
|
||||
session.setFetchBatchSize(5);
|
||||
session.setSubselectFetchingEnabled(true);
|
||||
----
|
||||
|
||||
[TIP]
|
||||
====
|
||||
|
@ -160,15 +159,24 @@ Set<Author> authors;
|
|||
Note that `@Fetch(SUBSELECT)` is equivalent to `@Fetch(SELECT)`, except after execution of a
|
||||
HQL or criteria query.
|
||||
|
||||
We'll see more of `@Fetch` when we discuss <<fetch-profiles,fetch profiles>>.
|
||||
Later, we'll see how we can use <<fetch-profiles,fetch profiles>> to do this even more selectively.
|
||||
====
|
||||
|
||||
That's all there is to it.
|
||||
Too easy, right?
|
||||
|
||||
Sadly, that's not the end of the story.
|
||||
While batch fetching might _mitigate_ problems involving N+1 selects, it won't solve them.
|
||||
The truly correct solution is to fetch associations using joins.
|
||||
Batch fetching (or subselect fetching) can only be the _best_ solution in rare cases where outer join fetching would result in a cartesian product and a huge result set.
|
||||
|
||||
Batch fetching and subselect fetching have one important characteristic in common: they can be performed _lazily_.
|
||||
|
||||
[[join-fetch]]
|
||||
==== Join fetching
|
||||
=== Join fetching
|
||||
|
||||
Unfortunately, outer join fetching, by nature, simply can't be lazy.
|
||||
So:
|
||||
|
||||
TIP: Avoid the use of lazy fetching, which is often the source of N+1 selects.
|
||||
|
||||
|
|
Loading…
Reference in New Issue