diff --git a/api/src/main/java/jakarta/persistence/EntityGraph.java b/api/src/main/java/jakarta/persistence/EntityGraph.java index 16444418..471d1e3f 100644 --- a/api/src/main/java/jakarta/persistence/EntityGraph.java +++ b/api/src/main/java/jakarta/persistence/EntityGraph.java @@ -24,6 +24,32 @@ * The methods to add subgraphs implicitly create the corresponding * attribute nodes as well; such attribute nodes should not be * redundantly specified. + *

+ * When used to specify fetching, an entity graph has two possible + * interpretations: + *

+ *

+ * An entity graph passed as the first argument to + * {@link EntityManager#find(EntityGraph, Object, FindOption...)} + * is interpreted as a load graph. + *

+ * 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 The type of the root entity. * @@ -36,6 +62,7 @@ * @see EntityManager#getEntityGraph(String) * @see EntityManagerFactory#addNamedEntityGraph(String, EntityGraph) * @see EntityManager#find(EntityGraph, Object, FindOption...) + * @see EntityManager#refresh(Object, EntityGraph) * * @since 2.1 */ diff --git a/api/src/main/java/jakarta/persistence/EntityManager.java b/api/src/main/java/jakarta/persistence/EntityManager.java index 80b41a19..df61bc19 100644 --- a/api/src/main/java/jakarta/persistence/EntityManager.java +++ b/api/src/main/java/jakarta/persistence/EntityManager.java @@ -885,6 +885,26 @@ 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 entity a managed entity instance + * @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 + */ + void refresh(T entity, EntityGraph entityGraph); + /** * Clear the persistence context, causing all managed entities to * become detached. Changes made to entities that have not already diff --git a/spec/src/main/asciidoc/ch03-entity-operations.adoc b/spec/src/main/asciidoc/ch03-entity-operations.adoc index 830e397b..16a8b83f 100644 --- a/spec/src/main/asciidoc/ch03-entity-operations.adoc +++ b/spec/src/main/asciidoc/ch03-entity-operations.adoc @@ -2071,7 +2071,7 @@ 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.