From 00682ec28eeedc222f27990a5cfe3e5842134254 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Mon, 27 Oct 2025 11:46:17 +0100 Subject: [PATCH 1/2] HHH-19892 signature of Session.merge() accepting EntityGraph --- .../src/main/java/org/hibernate/Session.java | 17 ++++++++++------- .../engine/spi/SessionDelegatorBaseImpl.java | 2 +- .../engine/spi/SessionLazyDelegator.java | 2 +- .../org/hibernate/internal/SessionImpl.java | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/Session.java b/hibernate-core/src/main/java/org/hibernate/Session.java index 9d9ae1593468..945aa0a6cbd5 100644 --- a/hibernate-core/src/main/java/org/hibernate/Session.java +++ b/hibernate-core/src/main/java/org/hibernate/Session.java @@ -706,18 +706,21 @@ public interface Session extends SharedSessionContract, EntityManager { /** * Copy the state of the given object onto the persistent object with the same * identifier. If there is no persistent instance currently associated with - * the session, it will be loaded. Return the persistent instance. If the - * given instance is unsaved, save a copy and return it as a newly persistent - * instance. The given instance does not become associated with the session. - * This operation cascades to associated instances if the association is mapped - * with {@link jakarta.persistence.CascadeType#MERGE}. + * the session, it is loaded using the given {@link EntityGraph}, which is + * interpreted as a load graph. Return the persistent instance. If the given + * instance is unsaved, save a copy and return it as a newly persistent instance. + * The given instance does not become associated with the session. This operation + * cascades to associated instances if the association is mapped with + * {@link jakarta.persistence.CascadeType#MERGE}. * * @param object a detached instance with state to be copied - * @param loadGraph entity graph interpreted as a load graph + * @param loadGraph an entity graph interpreted as a load graph * * @return an updated persistent instance + * + * @since 7.0 */ - T merge( T object, EntityGraph loadGraph); + T merge(T object, EntityGraph loadGraph); /** * Make a transient instance persistent and mark it for later insertion in the diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java index d66c9cc18f6c..eb0c8bb48942 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java @@ -846,7 +846,7 @@ public T merge(String entityName, T object) { } @Override - public T merge(T object, EntityGraph loadGraph) { + public T merge(T object, EntityGraph loadGraph) { return delegate.merge( object, loadGraph ); } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionLazyDelegator.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionLazyDelegator.java index 13bfb10a7ee7..19fbf55a7a03 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionLazyDelegator.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionLazyDelegator.java @@ -213,7 +213,7 @@ public T merge(String entityName, T object) { } @Override - public T merge(T object, EntityGraph loadGraph) { + public T merge(T object, EntityGraph loadGraph) { return this.lazySession.get().merge( object, loadGraph ); } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java index cb8d941f58bd..9675d90af229 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java @@ -758,7 +758,7 @@ public T merge(String entityName, T object) { } @Override - public T merge(T object, EntityGraph loadGraph) { + public T merge(T object, EntityGraph loadGraph) { final var effectiveEntityGraph = loadQueryInfluencers.getEffectiveEntityGraph(); try { effectiveEntityGraph.applyGraph( (RootGraphImplementor) loadGraph, GraphSemantic.LOAD ); From 2e5650de56d86e3119dbc154b5fd5225532f4570 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Mon, 27 Oct 2025 12:18:12 +0100 Subject: [PATCH 2/2] HHH-19892 fix the test --- .../test/entitygraph/LoadGraphMergeTest.java | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/entitygraph/LoadGraphMergeTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/entitygraph/LoadGraphMergeTest.java index 25af02633625..ec4be504b110 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/entitygraph/LoadGraphMergeTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/entitygraph/LoadGraphMergeTest.java @@ -19,9 +19,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import java.util.Collections; -import static org.hibernate.jpa.SpecHints.HINT_SPEC_LOAD_GRAPH; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -58,21 +56,11 @@ public static void init(EntityManagerFactoryScope scope) { @Test public void testGrandChildHasNotBeenInitializedByMerge(EntityManagerFactoryScope scope) { Parent parent = scope.fromTransaction( entityManager -> - entityManager.find( - Parent.class, - PARENT_ID_1, - Collections.singletonMap( - HINT_SPEC_LOAD_GRAPH, - entityManager.getEntityGraph( "parent.child" ) ) ) + entityManager.find( LoadGraphMergeTest_.Parent_._parent_child, PARENT_ID_1 ) ); Parent parent2 = scope.fromTransaction( entityManager -> - entityManager.find( - Parent.class, - PARENT_ID_2, - Collections.singletonMap( - HINT_SPEC_LOAD_GRAPH, - entityManager.getEntityGraph( "parent.child" ) ) ) + entityManager.find( LoadGraphMergeTest_.Parent_._parent_child, PARENT_ID_2) ); scope.inTransaction( entityManager -> { @@ -81,8 +69,7 @@ public void testGrandChildHasNotBeenInitializedByMerge(EntityManagerFactoryScope Session session = entityManager.unwrap( Session.class ); - Parent mergedParent = session.merge( parent, - entityManager.getEntityGraph( "parent.child" ) ); + Parent mergedParent = session.merge( parent, LoadGraphMergeTest_.Parent_._parent_child ); Child child = mergedParent.getChild(); assertTrue( Hibernate.isInitialized( child ) ); @@ -113,7 +100,7 @@ public void testChildHasNotBeenInitializedByMerge(EntityManagerFactoryScope scop assertFalse( Hibernate.isInitialized( child1 ) ); Session session = entityManager.unwrap( Session.class ); - Parent mergedParent = session.merge( parent, session.createEntityGraph( "parent" ) ); + Parent mergedParent = session.merge( parent, LoadGraphMergeTest_.Parent_._parent ); Child child = mergedParent.getChild(); assertFalse( Hibernate.isInitialized( child ),