From 03ee5445f88bbb120084ca234bb1251d412142de Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Tue, 28 Mar 2023 12:39:11 +0200 Subject: [PATCH] HHH-16272 Hibernate 6 fails to refresh when collections are accessed in entity setter method when access type is property --- .../entity/AbstractEntityInitializer.java | 21 +++++++------------ .../internal/EntityResultInitializer.java | 14 +++++++++++++ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java index 2240d25dcc..2467ccb2e7 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java @@ -52,7 +52,6 @@ import org.hibernate.sql.results.graph.DomainResultAssembler; import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.Initializer; import org.hibernate.sql.results.graph.basic.BasicResultAssembler; -import org.hibernate.sql.results.graph.entity.internal.EntityResultInitializer; import org.hibernate.sql.results.internal.NullValueAssembler; import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions; import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingState; @@ -498,10 +497,9 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces final PersistenceContext persistenceContext = rowProcessingState.getSession().getPersistenceContextInternal(); final Object proxy = getProxy( persistenceContext ); - final Object entityInstanceFromExecutionContext = - rowProcessingState.getJdbcValuesSourceProcessingState().getExecutionContext().getEntityInstance(); + final Object entityInstanceFromExecutionContext = getEntityInstanceFromExecutionContext( rowProcessingState ); if ( isProxyInstance( proxy ) ) { - if ( useEntityInstanceFromExecutionContext( entityInstanceFromExecutionContext, persistenceContext.getSession() ) ) { + if ( entityInstanceFromExecutionContext != null ) { entityInstance = entityInstanceFromExecutionContext; registerLoadingEntity( rowProcessingState, entityInstance ); } @@ -518,7 +516,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces this.isInitialized = true; } } - else if ( useEntityInstanceFromExecutionContext( entityInstanceFromExecutionContext, persistenceContext.getSession() ) ) { + else if ( entityInstanceFromExecutionContext != null ) { entityInstance = entityInstanceFromExecutionContext; registerLoadingEntity( rowProcessingState, entityInstance ); } @@ -532,13 +530,8 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces } } - private boolean useEntityInstanceFromExecutionContext( - Object entityInstanceFromExecutionContext, - SharedSessionContractImplementor session) { - return this instanceof EntityResultInitializer - && entityInstanceFromExecutionContext != null - && entityKey.getIdentifier() - .equals( entityDescriptor.getIdentifier( entityInstanceFromExecutionContext, session ) ); + protected Object getEntityInstanceFromExecutionContext(RowProcessingState rowProcessingState) { + return null; } private void upgradeLockMode(RowProcessingState rowProcessingState) { @@ -803,8 +796,6 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces ); } - entityDescriptor.setIdentifier( toInitialize, entityIdentifier, session ); - resolvedEntityState = extractConcreteTypeStateValues( rowProcessingState ); if ( isPersistentAttributeInterceptable(toInitialize) ) { @@ -859,6 +850,8 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces ); } + assert concreteDescriptor.getIdentifier( entityInstance, session ) != null; + final StatisticsImplementor statistics = session.getFactory().getStatistics(); if ( statistics.isStatisticsEnabled() ) { if ( !rowProcessingState.isQueryCacheHit() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultInitializer.java index 157af70aaf..b43d63d450 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultInitializer.java @@ -8,12 +8,14 @@ package org.hibernate.sql.results.graph.entity.internal; import org.hibernate.LockMode; import org.hibernate.spi.NavigablePath; +import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.results.graph.AssemblerCreationState; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.basic.BasicFetch; import org.hibernate.sql.results.graph.entity.AbstractEntityInitializer; import org.hibernate.sql.results.graph.entity.EntityResultGraphNode; +import org.hibernate.sql.results.jdbc.spi.RowProcessingState; /** * Initializer for cases where the entity is a root domain selection @@ -57,4 +59,16 @@ public class EntityResultInitializer extends AbstractEntityInitializer { return CONCRETE_NAME + "(" + getNavigablePath() + ")"; } + @Override + protected Object getEntityInstanceFromExecutionContext(RowProcessingState rowProcessingState) { + final ExecutionContext executionContext = rowProcessingState.getJdbcValuesSourceProcessingState() + .getExecutionContext(); + final Object entityInstanceFromExecutionContext = executionContext.getEntityInstance(); + if ( entityInstanceFromExecutionContext != null + && getEntityKey().getIdentifier().equals( executionContext.getEntityId() ) ) { + return entityInstanceFromExecutionContext; + } + return null; + } + }