From e12b82033e9f2be60711db4d0140bc51aaad4ead Mon Sep 17 00:00:00 2001 From: Gavin Date: Mon, 22 May 2023 17:10:21 +0200 Subject: [PATCH] HHH-16666 document fetch profiles now they are nicer to use --- .../main/asciidoc/introduction/Advanced.adoc | 92 +++++++++++++++++++ .../main/asciidoc/introduction/Tuning.adoc | 4 +- 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/documentation/src/main/asciidoc/introduction/Advanced.adoc b/documentation/src/main/asciidoc/introduction/Advanced.adoc index 288a12e69d..ff27e002d5 100644 --- a/documentation/src/main/asciidoc/introduction/Advanced.adoc +++ b/documentation/src/main/asciidoc/introduction/Advanced.adoc @@ -688,3 +688,95 @@ byte[] image; Interception is able to detect writes to the `image` field, that is, replacement of the whole array. It's not able to detect modifications made directly to the _elements_ of the array, and so such modifications may be lost. ==== + +[[fetch-profiles]] +=== Named fetch profiles + +We've already seen two different ways to override the default <> for an association: + +- <>, and +- the `join fetch` clause in <>, or, equivalently, the method `From.fetch()` in the criteria query API. + +A third way is to define a named fetch profile. +First, we must declare the profile, by annotating a class or package: + +[source,java] +---- +@FetchProfile(name = "EagerBook") +@Entity +class Book { ... } +---- + +Note that even though we've placed this annotation on the `Book` entity, a fetch profile—unlike an entity graph—isn't "rooted" at any particular entity. + +We may specify association fetching strategies using the `fetchOverrides` member of the `@FetchProfile` annotation, but frankly it looks so messy that we're embarrassed to show it to you here. + +A better way is to annotate an association with the fetch profiles it should be fetched in: + +[source,java] +---- +@FetchProfile(name = "EagerBook") +@Entity +class Book { + ... + + @ManyToOne(fetch = LAZY) + @Fetch(profile = "EagerBook", value = JOIN) + Publisher publisher; + + @ManyToMany + @Fetch(profile = "EagerBook", value = JOIN) + Set authors; + + ... +} +---- +[source,java] +---- +@Entity +class Author { + ... + + @OneToOne + @Fetch(profile = "EagerBook", value = JOIN) + Person person; + + ... +} +---- + +We may define as many different fetch profiles as we like. + +[NOTE] +==== +JPA entity graphs may also be defined in annotations, using `@NamedEntityGraph`. +But the format of this annotation is _even worse_ than the format of the `@FetchProfile` annotation, so we can't recommend it. 💀 +==== + +.Annotations for defining fetch profiles +[%autowidth.stretch] +|=== +| Annotation | Purpose + +| `@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 +|=== + +A fetch profile must be explicitly enabled for a given session: + +[source,java] +---- +session.enableFetchProfile("EagerBook"); +Book eagerBook = session.find(Book.class, bookId); +---- + +[TIP] +==== +To make this a bit typesafe, it's a really good idea to put the name of the fetch profile in a `static final` constant. +==== + +So why might we prefer named fetch profiles to entity graphs? +Well, that's really hard to say. +It's nice that this feature _exists_, and if you love it, that's great. +But Hibernate offers alternatives that we think are more compelling most of the time. diff --git a/documentation/src/main/asciidoc/introduction/Tuning.adoc b/documentation/src/main/asciidoc/introduction/Tuning.adoc index 72d574d84d..4da6e5b1d8 100644 --- a/documentation/src/main/asciidoc/introduction/Tuning.adoc +++ b/documentation/src/main/asciidoc/introduction/Tuning.adoc @@ -161,9 +161,9 @@ It's saying that you must explicitly specify eager fetching for associations pre If you need eager fetching in some particular transaction, use: - `left join fetch` in HQL, -- `fetch()` in a criteria query, +- `From.fetch()` in a criteria query, - a JPA `EntityGraph`, or -- a fetch profile. +- a <>. You can find much more information about association fetching in the {association-fetching}[User Guide].