Javadoc for FetchMode, @Fetch, and @BatchSize

This commit is contained in:
Gavin King 2022-11-10 00:12:12 +01:00
parent bd7140eef7
commit 51e2531c9c
4 changed files with 92 additions and 17 deletions

View File

@ -18,6 +18,7 @@ package org.hibernate;
*
* @author Gavin King
*/
@Internal
public enum FetchMode {
/**

View File

@ -15,8 +15,17 @@ import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Specifies a batch size for batch fetching of the annotated entity or
* collection.
* Specifies a maximum batch size for batch fetching of the annotated
* entity or collection.
* <p>
* When batch fetching is enabled, Hibernate is able to fetch multiple
* instances of an entity or collection in a single round-trip to the
* database. Instead of a SQL {@code select} with just one primary key
* value in the {@code where} clause, the {@code where} clause contains
* a list of primary keys inside a SQL {@code in} condition. The primary
* key values to batch fetch are chosen from among the identifiers of
* unfetched entity proxies or collection roles associated with the
* session.
* <p>
* For example:
* <pre>
@ -26,13 +35,17 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* ...
* }
* </pre>
* will initialize up to 100 lazy Product entity proxies at a time, but:
* will initialize up to 100 unfetched {@code Product} proxies in each
* trip to the database.
* <p>
* Similarly:
* <pre>
* &#64;OneToMany
* &#64;BatchSize(size = 5) /
* Set&lt;Product&gt; getProducts() { ... };
* </pre>
* will initialize up to 5 lazy collections of products at a time.
* will initialize up to 5 unfetched collections of {@code Product}s in
* each SQL {@code select}.
*
* @see org.hibernate.cfg.AvailableSettings#DEFAULT_BATCH_FETCH_SIZE
*
@ -43,7 +56,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
public @interface BatchSize {
/**
* Strictly positive integer.
* The maximum batch size, a strictly positive integer.
*/
int size();
}

View File

@ -14,8 +14,16 @@ import java.lang.annotation.Target;
/**
* Specifies the default fetching strategy for the annotated association.
* <p>
* The default fetching strategy for the association may be overridden
* in a given {@linkplain FetchProfile fetch profile}.
* When this annotation is <em>not</em> explicitly specified, then:
* <ul>
* <li>{@linkplain FetchMode#SELECT select fetching} is used for
* {@linkplain jakarta.persistence.FetchType#LAZY lazy} fetching,
* and
* <li>{@linkplain FetchMode#JOIN join fetching} is used for
* {@linkplain jakarta.persistence.FetchType#EAGER eager} fetching.
* </ul>
* The default fetching strategy specified by this annotation may be
* overridden in a given {@linkplain FetchProfile fetch profile}.
*
* @author Emmanuel Bernard
*

View File

@ -7,28 +7,81 @@
package org.hibernate.annotations;
/**
* How the association should be fetched.
*
* Defines the "how", compared to {@link jakarta.persistence.FetchType} which defines "when"
* Enumerates strategies for fetching an association from the database.
* <p>
* The JPA-defined {@link jakarta.persistence.FetchType} enumerates the
* possibilities for <em>when</em> an association might be fetched. This
* annotation defines <em>how</em> it is fetched in terms of the actual
* SQL executed by the database.
*
* @author Steve Ebersole
* @author Emmanuel Bernard
*
* @see Fetch
* @see FetchProfile.FetchOverride#mode()
*/
public enum FetchMode {
/**
* Use a secondary select for each individual entity, collection, or join load.
* Use a secondary select to load a single associated entity or
* collection, at some point after an initial query is executed.
* <p>
* This is the default fetching strategy for any association
* or collection in Hibernate, unless the association or
* collection is {@linkplain jakarta.persistence.FetchType#EAGER
* explicitly marked for eager fetching}.
* <p>
* This fetching strategy is vulnerable to the "N+1 selects"
* bugbear, though the impact may be alleviated somewhat via:
* <ul>
* <li>enabling batch fetching using {@link BatchSize}, or
* <li>ensuring that the associated entity or collection may be
* retrieved from the {@linkplain Cache second-level cache}.
* </ul>
* This fetching strategy is, in principle, compatible with both
* {@linkplain jakarta.persistence.FetchType#EAGER eager} and
* {@linkplain jakarta.persistence.FetchType#LAZY lazy} fetching.
* On the other hand, performance considerations dictate that it
* should only be used in combination wih {@code EAGER} fetching
* when it is almost certain that the associated data will be
* available in the second-level cache.
*/
SELECT( org.hibernate.FetchMode.SELECT ),
/**
* Use an outer join to load the related entities, collections or joins.
* Use an outer join to load all instances of the related entity
* or collection at once, as part of the execution of a query.
* No subsequent queries are executed.
* <p>
* This is the default fetching strategy for an association or
* collection that is {@linkplain jakarta.persistence.FetchType#EAGER
* explicitly marked for eager fetching}.
* <p>
* This fetching strategy is incompatible with
* {@linkplain jakarta.persistence.FetchType#LAZY lazy fetching}
* since the associated data is retrieved as part of the initial
* query.
*/
JOIN( org.hibernate.FetchMode.JOIN ),
/**
* Available for collections only.
*
* When accessing a non-initialized collection, this fetch mode will trigger
* loading all elements of all collections of the same role for all owners
* associated with the persistence context using a single secondary select.
* Use a secondary select with a subselect that re-executes an
* initial query to load all instances of the related entity or
* collection at once, at some point after the initial query is
* executed. This fetching strategy is currently only available
* for collections and many-valued associations.
* <p>
* This advanced fetching strategy is compatible with both
* {@linkplain jakarta.persistence.FetchType#EAGER eager} and
* {@linkplain jakarta.persistence.FetchType#LAZY lazy} fetching.
* <p>
* Subselect fetching may be contrasted with {@linkplain BatchSize
* batch fetching}:
* <ul>
* <li>In batch fetching, a list of primary key values is sent to
* the database, bound within a SQL {@code in} condition.
* <li>In subselect fetching, the primary keys are determined by
* re-execution of the initial query within a SQL subselect.
* </ul>
*/
SUBSELECT( org.hibernate.FetchMode.SELECT );