[[fetching]]
== Fetching
:sourcedir: ../../../../../test/java/org/hibernate/userguide/fetching
:extrasdir: extras

Fetching, essentially, is the process of grabbing data from the database and making it available to the application.
Tuning how an application does fetching is one of the biggest factors in determining how an application will perform.
Fetching too much data, in terms of width (values/columns) and/or depth (results/rows),
adds unnecessary overhead in terms of both JDBC communication and ResultSet processing.
Fetching too little data might cause additional fetching to be needed.
Tuning how an application fetches data presents a great opportunity to influence the overall application performance.

[[fetching-basics]]
=== The basics

The concept of fetching breaks down into two different questions.

* When should the data be fetched? Now? Later?
* How should the data be fetched?

[NOTE]
====
"Now" is generally termed eager or immediate while "later" is generally termed lazy or delayed.
====

There are a number of scopes for defining fetching:

_static_::
	Static definition of fetching strategies is done in the mappings.
	The statically-defined fetch strategies are used in the absence of any dynamically defined strategies.
    SELECT:::
		Performs a separate SQL select to load the data. This can either be EAGER (the second select is issued immediately) or LAZY (the second select is delayed until the data is needed).
		This is the strategy generally termed N+1.
    JOIN:::
      	Inherently an EAGER style of fetching. The data to be fetched is obtained through the use of an SQL outer join.
    BATCH:::
      	Performs a separate SQL select to load a number of related data items using an IN-restriction as part of the SQL WHERE-clause based on a batch size.
      	Again, this can either be EAGER (the second select is issued immediately) or LAZY (the second select is delayed until the data is needed).
    SUBSELECT:::
      	Performs a separate SQL select to load associated data based on the SQL restriction used to load the owner.
      	Again, this can either be EAGER (the second select is issued immediately) or LAZY (the second select is delayed until the data is needed).
_dynamic_ (sometimes referred to as runtime)::
	The dynamic definition is really use-case centric. There are multiple ways to define dynamic fetching:
    fetch profiles::: defined in mappings, but can be enabled/disabled on the `Session`.
    HQL / JPQL::: both Hibernate and JPA Criteria queries have the ability to specify fetching, specific to said query.
    entity graphs::: starting in Hibernate 4.2 (JPA 2.1), this is also an option.

[[fetching-direct-vs-query]]
=== Direct fetching vs. entity queries

To see the difference between direct fetching and entity queries in regard to eagerly fetched associations, consider the following entities:

[[fetching-direct-vs-query-domain-model-example]]
.Domain model
====
[source, JAVA, indent=0]
----
include::{sourcedir}/DirectVsQueryFetchingTest.java[tags=fetching-direct-vs-query-domain-model-example]
----
====

The `Employee` entity has a `@ManyToOne` association to a `Department` which is fetched eagerly.

When issuing a direct entity fetch, Hibernate executed the following SQL query:

[[fetching-direct-vs-query-direct-fetching-example]]
.Direct fetching example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/DirectVsQueryFetchingTest.java[tags=fetching-direct-vs-query-direct-fetching-example]
----

[source, SQL, indent=0]
----
include::{extrasdir}/fetching-direct-vs-query-direct-fetching-example.sql[]
----
====

The `LEFT JOIN` clause is added to the generated SQL query because this association is required to be fetched eagerly.

On the other hand, if you are using an entity query that does not contain a `JOIN FETCH` directive to the `Department` association:

[[fetching-direct-vs-query-entity-query-example]]
.Entity query fetching example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/DirectVsQueryFetchingTest.java[tags=fetching-direct-vs-query-entity-query-example]
----

[source, SQL, indent=0]
----
include::{extrasdir}/fetching-direct-vs-query-entity-query-example.sql[]
----
====

Hibernate uses a secondary select instead. This is because the entity query fetch policy cannot be overridden,
so Hibernate requires a secondary select to ensure that the EAGER association is fetched prior to returning the result to the user.

[IMPORTANT]
====
If you forget to JOIN FETCH all EAGER associations, Hibernate is going to issue a secondary select for each and every one of those
which, in turn, can lead to N+1 query issues.

For this reason, you should prefer LAZY associations.
====

[[fetching-strategies]]
=== Applying fetch strategies

Let's consider these topics as it relates to a simple domain model and a few use cases.

[[fetching-strategies-domain-model-example]]
.Sample domain model
====
[source, JAVA, indent=0]
----
include::{sourcedir}/FetchingTest.java[tags=fetching-strategies-domain-model-example]
----
====

[IMPORTANT]
====
The Hibernate recommendation is to statically mark all associations lazy and to use dynamic fetching strategies for eagerness.

This is unfortunately at odds with the JPA specification which defines that all one-to-one and many-to-one associations should be eagerly fetched by default.

Hibernate, as a JPA provider, honors that default.
====

[[fetching-strategies-no-fetching]]
=== No fetching

For the first use case, consider the application login process for an `Employee`.
Let's assume that login only requires access to the `Employee` information, not `Project` nor `Department` information.

[[fetching-strategies-no-fetching-example]]
.No fetching example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/FetchingTest.java[tags=fetching-strategies-no-fetching-example]
----
====

In this example, the application gets the `Employee` data.
However, because all associations from `Employee` are declared as LAZY (JPA defines the default for collections as LAZY) no other data is fetched.

If the login process does not need access to the `Employee` information specifically, another fetching optimization here would be to limit the width of the query results.

[[fetching-strategies-no-fetching-scalar-example]]
.No fetching (scalar) example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/FetchingTest.java[tags=fetching-strategies-no-fetching-scalar-example]
----
====

[[fetching-strategies-dynamic-fetching]]
=== Dynamic fetching via queries

For the second use case, consider a screen displaying the `Projects` for an `Employee`.
Certainly access to the `Employee` is needed, as is the collection of `Projects` for that Employee. Information about `Departments`, other `Employees` or other `Projects` is not needed.

[[fetching-strategies-dynamic-fetching-jpql-example]]
.Dynamic JPQL fetching example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/FetchingTest.java[tags=fetching-strategies-dynamic-fetching-jpql-example]
----
====

[[fetching-strategies-dynamic-fetching-criteria-example]]
.Dynamic query fetching example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/FetchingTest.java[tags=fetching-strategies-dynamic-fetching-criteria-example]
----
====

In this example we have an `Employee` and their `Projects` loaded in a single query shown both as an HQL query and a JPA Criteria query.
In both cases, this resolves to exactly one database query to get all that information.

[[fetching-strategies-dynamic-fetching-entity-graph]]
=== Dynamic fetching via JPA entity graph

JPA 2.1 introduced entity graphs so the application developer has more control over fetch plans.

[[fetching-strategies-dynamic-fetching-entity-graph-example]]
.Fetch graph example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/GraphFetchingTest.java[tags=fetching-strategies-dynamic-fetching-entity-graph-mapping-example]
----

[source, JAVA, indent=0]
----
include::{sourcedir}/GraphFetchingTest.java[tags=fetching-strategies-dynamic-fetching-entity-graph-example]
----
====

[NOTE]
====
When executing a JPQL query, if an EAGER association is omitted, Hibernate will issue a secondary select for every association needed to be fetched eagerly,
which can lead to N+1 query issues.

For this reason, it's better to use LAZY associations, and only fetch them eagerly on a per-query basis.
====

An EntityGraph is the root of a "load plan" and must correspond to an EntityType.


[[fetching-strategies-dynamic-fetching-entity-subgraph]]
==== JPA (key) subgraphs

A sub-graph is used to control the fetching of sub-attributes of the AttributeNode it is applied to.
It is generally defined via the https://javaee.github.io/javaee-spec/javadocs/javax/persistence/NamedSubgraph.html[`@NamedSubgraph`] annotation.

If we have a `Project` parent entity which has an `employees` child associations,
and we'd like to fetch the `department` for the `Employee` child association.

[[fetching-strategies-dynamic-fetching-entity-subgraph-mapping-example]]
.Fetch graph with a subgraph mapping
====
[source, JAVA, indent=0]
----
include::{sourcedir}/GraphFetchingTest.java[tags=fetching-strategies-dynamic-fetching-entity-subgraph-mapping-example]
----
====

When fetching this entity graph, Hibernate generates the following SQL query:

[[fetching-strategies-dynamic-fetching-entity-subgraph-example]]
.Fetch graph with a subgraph mapping
====
[source, JAVA, indent=0]
----
include::{sourcedir}/GraphFetchingTest.java[tags=fetching-strategies-dynamic-fetching-entity-subgraph-example]
----

[source, SQL, indent=0]
----
include::{extrasdir}/fetching-strategies-dynamic-fetching-entity-subgraph-example.sql[]
----
====

Specifying a sub-graph is only valid for an attribute (or its "key") whose type is a ManagedType.  So
while an EntityGraph must correspond to an EntityType, a Subgraph is legal for any ManagedType.  An
attribute's key is defined as either:

* For a singular attribute, the attribute's type must be an IdentifiableType and that IdentifiableType must
	have a composite identifier.  The "key sub-graph" is applied to the identifier type.  The
	non-key sub-graph applies to the attribute's value, which must be a ManagedType.
* For a plural attribute, the attribute must be a Map and the Map's key value must be a ManagedType.
	The "key sub-graph" is applied to the Map's key type.  In this case, the non-key sub-graph applies
	to the plural attribute's value/element.


[[fetching-strategies-dynamic-fetching-entity-subgraph-subtype]]
==== JPA SubGraph sub-typing

SubGraphs can also be sub-type specific.  Given an attribute whose value is an inheritance hierarchy,
we can refer to attributes of a specific sub-type using the forms of sub-graph definition that accept
the sub-type Class.


[[fetching-strategies-dynamic-fetching-entity-graph-parsing]]
==== Creating and applying JPA graphs from text representations

Hibernate allows the creation of JPA fetch/load graphs by parsing a textual representation
of the graph.  Generally speaking, the textual representation of a graph is a comma-separated
list of attribute names, optionally including any sub-graph specifications.
`org.hibernate.graph.EntityGraphParser` is the starting point for such parsing operations.

[NOTE]
====
Parsing a textual representation of a graph is not (yet) a part of the JPA specification. So the
syntax described here is specific to Hibernate. We do hope to eventually make this syntax part of
the JPA specification proper.
====


.Parsing a simple graph
====
[source, JAVA, indent=0]
----
include::{sourcedir}/GraphParsingTest.java[tags=fetching-strategies-dynamic-fetching-entity-graph-parsing-example-1]
----
====

This example actually functions exactly as <<fetching-strategies-dynamic-fetching-entity-subgraph-example>>,
just using a parsed graph rather than a named graph.


The syntax also supports defining "key sub-graphs".  To specify a key sub-graph, `.key` is added
to the end of the attribute name.

.Parsing an entity key graph
====
[source, JAVA, indent=0]
----
include::{sourcedir}/GraphParsingTest.java[tags=fetching-strategies-dynamic-fetching-entity-graph-parsing-key-example-1]
----
====

.Parsing a map key graph
====
[source, JAVA, indent=0]
----
include::{sourcedir}/GraphParsingTest.java[tags=fetching-strategies-dynamic-fetching-entity-graph-parsing-key-example-2]
----
====

Parsing can also handle sub-type specific sub-graphs.  For example, given an entity hierarchy of
`LegalEntity` <- (`Corporation` | `Person` | `NonProfit`) and an attribute named `responsibleParty` whose
type is the `LegalEntity` base type we might have:

====
[source, JAVA, indent=0]
----
responsibleParty(Corporation: ceo)
----
====

We can even duplicate the attribute names to apply different sub-type sub-graphs:

====
[source, JAVA, indent=0]
----
responsibleParty(taxIdNumber), responsibleParty(Corporation: ceo), responsibleParty(NonProfit: sector)
----
====

The duplicated attribute names are handled according to the JPA specification which says that duplicate
specification of the attribute node results in the originally registered AttributeNode to be re-used
effectively merging the 2 AttributeNode specifications together.  In other words, the above specification
creates a single AttributeNode with 3 distinct SubGraphs.  It is functionally the same as calling:

====
[source, JAVA, indent=0]
----
Class<Invoice> invoiceClass = ...;
javax.persistence.EntityGraph<Invoice> invoiceGraph = entityManager.createEntityGraph( invoiceClass );
invoiceGraph.addAttributeNode( "responsibleParty" );
invoiceGraph.addSubgraph( "responsibleParty" ).addAttributeNode( "taxIdNumber" );
invoiceGraph.addSubgraph( "responsibleParty", Corporation.class ).addAttributeNode( "ceo" );
invoiceGraph.addSubgraph( "responsibleParty", NonProfit.class ).addAttributeNode( "sector" );
----
====

[[fetching-strategies-dynamic-fetching-entity-graph-merging]]
==== Combining multiple JPA entity graphs into one

Multiple entity graphs can be combined into a single "super graph" that acts as a union. Graph from
the previous example can also be built by combining separate aspect graphs into one, such as:

.Combining multiple graphs into one
====
[source, JAVA, indent=0]
----
include::{sourcedir}/GraphParsingTest.java[tags=fetching-strategies-dynamic-fetching-entity-graph-merging-example]
----
====


[[fetching-strategies-dynamic-fetching-profile]]
=== Dynamic fetching via Hibernate profiles

Suppose we wanted to leverage loading by natural-id to obtain the `Employee` information in the "projects for and employee" use-case.
Loading by natural-id uses the statically defined fetching strategies, but does not expose a means to define load-specific fetching.
So we would leverage a fetch profile.

[[fetching-strategies-dynamic-fetching-profile-example]]
.Fetch profile example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/ProfileFetchingTest.java[tags=fetching-strategies-dynamic-fetching-profile-mapping-example]
----

[source, JAVA, indent=0]
----
include::{sourcedir}/ProfileFetchingTest.java[tags=fetching-strategies-dynamic-fetching-profile-example]
----
====

Here the `Employee` is obtained by natural-id lookup and the Employee's `Project` data is fetched eagerly.
If the `Employee` data is resolved from cache, the `Project` data is resolved on its own.
However, if the `Employee` data is not resolved in cache, the `Employee` and `Project` data is resolved in one SQL query via join as we saw above.

[[fetching-batch]]
=== Batch fetching

Hibernate offers the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/BatchSize.html[`@BatchSize`] annotation,
which can be used when fetching uninitialized entity proxies.

Considering the following entity mapping:

[[fetching-batch-mapping-example]]
.`@BatchSize` mapping example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/BatchFetchingTest.java[tags=fetching-batch-mapping-example]
----
====

Considering that we have previously fetched several `Department` entities,
and now we need to initialize the `employees` entity collection for each particular `Department`,
the `@BatchSize` annotations allows us to load multiple `Employee` entities in a single database roundtrip.

[[fetching-batch-fetching-example]]
.`@BatchSize` fetching example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/BatchFetchingTest.java[tags=fetching-batch-fetching-example]
----

[source, SQL, indent=0]
----
include::{extrasdir}/fetching-batch-fetching-example.sql[]
----
====

As you can see in the example above, there are only two SQL statements used to fetch the `Employee` entities associated with multiple `Department` entities.

[TIP]
====
Without `@BatchSize`, you'd run into a N+1 query issue, so,
instead of 2 SQL statements, there would be 10 queries needed for fetching the `Employee` child entities.

However, although `@BatchSize` is better than running into an N+1 query issue,
most of the time, a DTO projection or a `JOIN FETCH` is a much better alternative since
it allows you to fetch all the required data with a single query.
====

[[fetching-fetch-annotation]]
=== The `@Fetch` annotation mapping

Besides the `FetchType.LAZY` or `FetchType.EAGER` JPA annotations,
you can also use the Hibernate-specific `@Fetch` annotation that accepts one of the following ``FetchMode``s:

SELECT::
	The association is going to be fetched lazily using a secondary select for each individual entity,
	collection, or join load.
	It's equivalent to JPA `FetchType.LAZY` fetching strategy.
JOIN::
	Use an outer join to load the related entities, collections or joins when using direct fetching.
	It's equivalent to JPA `FetchType.EAGER` fetching strategy.
SUBSELECT::
	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.

[[fetching-fetchmode-select]]
=== `FetchMode.SELECT`

To demonstrate how `FetchMode.SELECT` works, consider the following entity mapping:

[[fetching-strategies-fetch-mode-select-mapping-example]]
.`FetchMode.SELECT` mapping example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/FetchModeSelectTest.java[tags=fetching-strategies-fetch-mode-select-mapping-example]
----
====

Considering there are multiple `Department` entities, each one having multiple `Employee` entities,
when executing the following test case, Hibernate fetches every uninitialized `Employee`
collection using a secondary `SELECT` statement upon accessing the child collection for the first time:

[[fetching-strategies-fetch-mode-select-example]]
.`FetchMode.SELECT` mapping example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/FetchModeSelectTest.java[tags=fetching-strategies-fetch-mode-select-example]
----

[source, SQL, indent=0]
----
include::{extrasdir}/fetching-strategies-fetch-mode-select-example.sql[]
----
====

The more `Department` entities are fetched by the first query, the more secondary `SELECT` statements are executed to initialize the `employees` collections.
Therefore, `FetchMode.SELECT` can lead to N+1 query issues.

[[fetching-fetchmode-subselect]]
=== `FetchMode.SUBSELECT`

To demonstrate how `FetchMode.SUBSELECT` works, we are going to modify the <<fetching-strategies-fetch-mode-select-mapping-example>> to use
`FetchMode.SUBSELECT`:

[[fetching-strategies-fetch-mode-subselect-mapping-example]]
.`FetchMode.SUBSELECT` mapping example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/FetchModeSubselectTest.java[tags=fetching-strategies-fetch-mode-subselect-mapping-example]
----
====

Now, we are going to fetch all `Department` entities that match a given filtering predicate
and then navigate their `employees` collections.

Hibernate is going to avoid the N+1 query issue by generating a single SQL statement to initialize all `employees` collections
for all `Department` entities that were previously fetched.
Instead of using passing all entity identifiers, Hibernate simply reruns the previous query that fetched the `Department` entities.

[[fetching-strategies-fetch-mode-subselect-example]]
.`FetchMode.SUBSELECT` mapping example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/FetchModeSubselectTest.java[tags=fetching-strategies-fetch-mode-subselect-example]
----

[source, SQL, indent=0]
----
include::{extrasdir}/fetching-strategies-fetch-mode-subselect-example.sql[]
----
====

[[fetching-fetchmode-join]]
=== `FetchMode.JOIN`

To demonstrate how `FetchMode.JOIN` works, we are going to modify the <<fetching-strategies-fetch-mode-select-mapping-example>> to use
`FetchMode.JOIN` instead:

[[fetching-strategies-fetch-mode-join-mapping-example]]
.`FetchMode.JOIN` mapping example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/FetchModeJoinTest.java[tags=fetching-strategies-fetch-mode-join-mapping-example]
----
====

Now, we are going to fetch one `Department` and navigate its `employees` collections.

[NOTE]
====
The reason why we are not using a JPQL query to fetch multiple `Department` entities is because
the `FetchMode.JOIN` strategy would be overridden by the query fetching directive.

To fetch multiple relationships with a JPQL query, the `JOIN FETCH` directive must be used instead.

Therefore, `FetchMode.JOIN` is useful for when entities are fetched directly, via their identifier or natural-id.

Also, the `FetchMode.JOIN` acts as a `FetchType.EAGER` strategy.
Even if we mark the association as `FetchType.LAZY`, the `FetchMode.JOIN` will load the association eagerly.
====

Hibernate is going to avoid the secondary query by issuing an OUTER JOIN for the `employees` collection.

[[fetching-strategies-fetch-mode-join-example]]
.`FetchMode.JOIN` mapping example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/FetchModeJoinTest.java[tags=fetching-strategies-fetch-mode-join-example]
----

[source, SQL, indent=0]
----
include::{extrasdir}/fetching-strategies-fetch-mode-join-example.sql[]
----
====

This time, there was no secondary query because the child collection was loaded along with the parent entity.

[[fetching-LazyCollection]]
=== `@LazyCollection`

The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/LazyCollection.html[`@LazyCollection`] annotation is used to specify the lazy fetching behavior of a given collection.
The possible values are given by the `https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/LazyCollectionOption.html[LazyCollectionOption]` enumeration:

`TRUE`:: Load it when the state is requested.
`FALSE`:: Eagerly load it.
`EXTRA`:: Prefer extra queries over full collection loading.

The `TRUE` and `FALSE` values are deprecated since you should be using the JPA https://javaee.github.io/javaee-spec/javadocs/javax/persistence/FetchType.html[`FetchType`] attribute of the <<annotations-jpa-elementcollection>>, <<annotations-jpa-onetomany>>, or <<annotations-jpa-manytomany>> collection.

The `EXTRA` value has no equivalent in the JPA specification, and it's used to avoid loading the entire collection even when the collection is accessed for the first time.
Each element is fetched individually using a secondary query.

[[fetching-LazyCollection-domain-model-example]]
.`LazyCollectionOption.EXTRA` mapping example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/LazyCollectionTest.java[tags=fetching-LazyCollection-domain-model-example]
----
====

[NOTE]
====
`LazyCollectionOption.EXTRA` only works for ordered collections,
either List(s) that are annotated with @OrderColumn or Map(s).

For bags (e.g. regular List(s) of entities that do not preserve any certain ordering),
the `@LazyCollection(LazyCollectionOption.EXTRA)` behaves like any other `FetchType.LAZY` collection
(the collection is fetched entirely upon being accessed for the first time).
====

Now, considering we have the following entities:

[[fetching-LazyCollection-persist-example]]
.`LazyCollectionOption.EXTRA` Domain Model example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/LazyCollectionTest.java[tags=fetching-LazyCollection-persist-example]
----
====

When fetching the `employee` collection entries by their position in the `List`,
Hibernate generates the following SQL statements:

[[fetching-LazyCollection-select-example]]
.`LazyCollectionOption.EXTRA` fetching example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/LazyCollectionTest.java[tags=fetching-LazyCollection-select-example]
----

[source, SQL, indent=0]
----
include::{extrasdir}/fetching-LazyCollection-select-example.sql[]
----
====

[WARNING]
====
Therefore, the child entities were fetched one after the other without triggering a full collection initialization.

For this reason, caution is advised since accessing all elements using `LazyCollectionOption.EXTRA` can lead to N+1 query issues.
====
