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)
|
@ManyToOne(fetch = LAZY)
|
||||||
@Fetch(profile = "EagerBook", value = JOIN)
|
@FetchProfileOverride(profile = "EagerBook", mode = JOIN)
|
||||||
Publisher publisher;
|
Publisher publisher;
|
||||||
|
|
||||||
@ManyToMany
|
@ManyToMany
|
||||||
@Fetch(profile = "EagerBook", value = JOIN)
|
@FetchProfileOverride(profile = "EagerBook", mode = JOIN)
|
||||||
Set<Author> authors;
|
Set<Author> authors;
|
||||||
|
|
||||||
...
|
...
|
||||||
|
@ -738,7 +738,7 @@ class Author {
|
||||||
...
|
...
|
||||||
|
|
||||||
@OneToOne
|
@OneToOne
|
||||||
@Fetch(profile = "EagerBook", value = JOIN)
|
@FetchProfileOverride(profile = "EagerBook", mode = JOIN)
|
||||||
Person person;
|
Person person;
|
||||||
|
|
||||||
...
|
...
|
||||||
|
@ -756,12 +756,12 @@ class Book {
|
||||||
...
|
...
|
||||||
|
|
||||||
@OneToOne
|
@OneToOne
|
||||||
@Fetch(profile = "EagerBook", value = JOIN)
|
@FetchProfileOverride(profile = "EagerBook", mode = JOIN)
|
||||||
Person person;
|
Person person;
|
||||||
|
|
||||||
@ManyToMany
|
@ManyToMany
|
||||||
@Fetch(profile = "EagerBook", value = JOIN)
|
@FetchProfileOverride(profile = "EagerBook", mode = JOIN)
|
||||||
@Fetch(profile = "BookWithAuthorsBySubselect", value = SUBSELECT)
|
@FetchProfileOverride(profile = "BookWithAuthorsBySubselect", mode = SUBSELECT)
|
||||||
Set<Author> authors;
|
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` | 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
|
| `@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:
|
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.
|
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.
|
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
|
=== 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.
|
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
|
.Configuration settings to enable batch and subselect fetching
|
||||||
[cols="35,~"]
|
[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
|
| `hibernate.use_subselect_fetch` | `true` to enable subselect fetching
|
||||||
|===
|
|===
|
||||||
|
|
||||||
That's all there is to it.
|
Alternatively, we can enable one or the other in a given session:
|
||||||
Too easy, right?
|
|
||||||
|
|
||||||
Sadly, that's not the end of the story.
|
[source,java]
|
||||||
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.
|
session.setFetchBatchSize(5);
|
||||||
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.
|
session.setSubselectFetchingEnabled(true);
|
||||||
|
----
|
||||||
|
|
||||||
[TIP]
|
[TIP]
|
||||||
====
|
====
|
||||||
|
@ -160,15 +159,24 @@ Set<Author> authors;
|
||||||
Note that `@Fetch(SUBSELECT)` is equivalent to `@Fetch(SELECT)`, except after execution of a
|
Note that `@Fetch(SUBSELECT)` is equivalent to `@Fetch(SELECT)`, except after execution of a
|
||||||
HQL or criteria query.
|
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_.
|
Batch fetching and subselect fetching have one important characteristic in common: they can be performed _lazily_.
|
||||||
|
|
||||||
[[join-fetch]]
|
[[join-fetch]]
|
||||||
==== Join fetching
|
=== Join fetching
|
||||||
|
|
||||||
Unfortunately, outer join fetching, by nature, simply can't be lazy.
|
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.
|
TIP: Avoid the use of lazy fetching, which is often the source of N+1 selects.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue