Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions api/src/main/java/jakarta/persistence/EntityGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

package jakarta.persistence;

import jakarta.persistence.metamodel.Attribute;

/**
* This type represents the root of an entity graph that will be
* used as a template to define the attribute nodes and boundaries
Expand All @@ -24,6 +26,41 @@
* The methods to add subgraphs implicitly create the corresponding
* attribute nodes as well; such attribute nodes should not be
* redundantly specified.
* <p>
* When used to specify fetching, an entity graph has three possible
* interpretations:
* <ul>
* <li>As a <em>load graph</em>, where every node explicitly added
* to or explicitly removed from the graph overrides the
* {@linkplain FetchType fetching strategy} of the attribute
* which was specified via annotations or XML descriptor, but
* the graph does not affect the fetching strategy of any
* attribute which was neither added to nor removed from the
* graph.
* <li>As a <em>fetch graph</em>, where the graph completely
* overrides every fetching strategy specified via annotations
* or XML descriptor, and every attribute not explicitly added
* to the graph is treated as {@link FetchType#LAZY}.
* <li>As a <em>refresh graph</em>, where every node explicitly added
* to or explicitly removed from the graph overrides the default
* behavior of refresh with respect to the corresponding attribute.
* The default behavior is to refresh every attribute of an entity
* being refreshed, without refreshing any associated entity.
* The method {@link #addSubgraph(Attribute)} specifies that an
* associated entity <em>should</em> be refreshed. The method
* {@link #removeAttributeNode(Attribute)} hints that an attribute
* of an entity being refreshed <em>should not</em> be refreshed.
* </ul>
* <p>
* An entity graph passed as the first argument to
* {@link EntityManager#find(EntityGraph, Object, FindOption...)}
* is interpreted as a load graph.
* <p>
* When an entity graph is passed to
* {@link EntityManager#refresh(Object, EntityGraph)}, the graph
* completely overrides the effect of {@code cascade=REFRESH}, and
* each node belonging to the graph is treated as an instruction
* to refresh the corresponding attribute.
*
* @param <T> The type of the root entity.
*
Expand All @@ -36,6 +73,7 @@
* @see EntityManager#getEntityGraph(String)
* @see EntityManagerFactory#addNamedEntityGraph(String, EntityGraph)
* @see EntityManager#find(EntityGraph, Object, FindOption...)
* @see EntityManager#refresh(Object, EntityGraph)
*
* @since 2.1
*/
Expand Down
23 changes: 23 additions & 0 deletions api/src/main/java/jakarta/persistence/EntityManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,29 @@ void refresh(Object entity, LockModeType lockMode,
void refresh(Object entity,
RefreshOption... options);

/**
* Refresh the state of the given managed entity instance from the
* database, along with all associated entities reachable by
* following the given {@link EntityGraph}, overwriting changes
* made to the entity, if any. This operation does not cascade to
* associations marked {@link CascadeType#REFRESH cascade=REFRESH}
* unless they are included in the given entity graph.
* @param entityGraph entity graph interpreted as a refresh graph
* @param entity a managed entity instance
* @param options standard and vendor-specific options
* @throws IllegalArgumentException if the instance is not an entity
* or if the entity is not managed
* @throws TransactionRequiredException if there is no
* transaction when invoked on a container-managed
* entity manager of type
* {@link PersistenceContextType#TRANSACTION}
* @throws EntityNotFoundException if the entity no longer exists in
* the database
* @since 4.0
*/
<T> void refresh(T entity, EntityGraph<T> entityGraph,
RefreshOption... options);

/**
* Clear the persistence context, causing all managed entities to
* become detached. Changes made to entities that have not already
Expand Down
89 changes: 58 additions & 31 deletions spec/src/main/asciidoc/ch03-entity-operations.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1867,45 +1867,47 @@ approach defined by the Bean Validation specification

=== Entity Graphs [[a2397]]

An entity graph is a template that captures
the path and boundaries for an operation or query. It is defined in the
form of metadata or an object created by the dynamic `EntityGraph` API.
An entity graph is a template that captures the extent of an operation or
query.

Entity graphs are used in the specification
of “fetch plans” for query or `find` operations.
- An entity graph may be used to specify a _fetch plan_ for a query or
`find()` operation.
- Alternatively, an entity graph may be used to specify a _refresh plan_
for a `refresh()` operation.

The `EntityGraph`, `AttributeNode`, and `Subgraph` interfaces found in
<<persistence-api>> are used to dynamically construct entity graphs.
An entity graph may be defined via metadata or by constructing an
instance of `EntityGraph` programmatically in application code.

The annotations `NamedEntityGraph`, `NamedAttributeNode`, and
`NamedSubgraph` described in <<a13662>> are used to statically define
entity graphs. The `named-entity-graph` XML element and its subelements
may be used to override these annotations or to define additional named
entity graphs.
- The `EntityGraph`, `AttributeNode`, and `Subgraph` interfaces found in
<<persistence-api>> are used to dynamically construct entity graphs.

The semantics of entity graphs with regard to
find and query operations are described in <<a2814>>.
- The annotations `NamedEntityGraph`, `NamedAttributeNode`, and
`NamedSubgraph` described in <<a13662>> are used to statically define
entity graphs. The `named-entity-graph` XML element and its subelements
may be used to override these annotations or to define additional named
entity graphs.

==== Use of Entity Graphs in find and query operations [[a2814]]
==== Fetch plans [[a2814]]

An entity graph can be used with the `find`
method or as a query hint to override or augment `FetchType` semantics.
An entity graph can be used with the `find()` method or as a query hint to
define a fetch plan which overrides or augments the `FetchType` semantics.
An entity graph used as a fetch plan may be interpreted as a _fetch graph_,
as specified below in <<fetch-graph>>, or as a _load graph_, as specified
below in <<load-graph>>.

The standard properties
`jakarta.persistence.fetchgraph` and `jakarta.persistence.loadgraph` are
used to specify such graphs to queries and `find` operations.
The default fetch graph for an entity or embeddable is defined to comprise
the transitive closure of all of its attributes which are specified as
`FetchType.EAGER` (or defaulted as such).

The default fetch graph for an entity or
embeddable is defined to consist of the transitive closure of all of its
attributes that are specified as `FetchType.EAGER` (or defaulted as
such).
The persistence provider is permitted to fetch additional entity state
beyond that which is specified by a fetch plan. It is required, however,
that the persistence provider fetch all state specified by the fetch plan.

The persistence provider is permitted to
fetch additional entity state beyond that specified by a fetch graph or
load graph. It is required, however, that the persistence provider fetch
all state specified by the fetch or load graph.
The standard properties `jakarta.persistence.fetchgraph` and
`jakarta.persistence.loadgraph` may be used to pass fetch plans to queries
and `find` operations.

===== Fetch Graph Semantics
===== Fetch Graph Semantics [[fetch-graph]]

When the `jakarta.persistence.fetchgraph`
property is used to specify an entity graph, attributes that are
Expand Down Expand Up @@ -2065,13 +2067,13 @@ Since the type of the `approver` attribute is `Employee`, the
approver's default fetch graph (`id`, `name`, and `employeeNumber`
attributes) would also be fetched.

===== Load Graph Semantics
===== Load Graph Semantics [[load-graph]]

When the `jakarta.persistence.loadgraph`
property is used to specify an entity graph, attributes that are
specified by attribute nodes of the entity graph are treated as
`FetchType.EAGER` and attributes that are not specified are treated
according to their specified or default FetchType.
according to their specified or default `FetchType`.

The following rules apply. The rules of this
section are applied recursively.
Expand Down Expand Up @@ -2206,6 +2208,31 @@ The default fetch graphs of the related `Project` instances (`id`,
`name`, and `doc` attributes) and their `Requirements` instances (`id`
and `description` attributes) are also fetched.

==== Refresh plans

An entity graph can be used with the `refresh()` method to define a refresh
plan which overrides or augments the default behavior of refresh. An entity
graph used as a refresh plan is interpreted as a _refresh graph_, as specified
below in <<refresh-graph>>

The default behavior is to refresh every attribute of an entity being
refreshed, without refreshing any associated entity.

The persistence provider is permitted to refresh additional entity state
beyond that which is specified by a refresh plan. It is required, however,
that the persistence provider fetch all state specified by the refresh plan.

===== Refresh Graph Semantics [[refresh-graph]]

A refresh plan includes every attribute of an entity being refreshed
by default, but does not include any associated entity.

- An attribute node may be explicitly removed from the refresh graph,
hinting that the attribute need not be refreshed.

- A subgraph may be added to the refresh graph, specifying that the
associated entity should be refreshed.

=== Type Conversion of Basic Attributes [[a2999]]

The attribute conversion facility allows the developer to define custom
Expand Down
Loading