From 70d8ed2ca2e08a34ca956e7b5f0b792db0b9d132 Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Mon, 12 Jun 2023 19:12:32 +0200 Subject: [PATCH] HHH-16744 Wrong class created when reusing a join column for different entities in multiple ManyToOne --- ...ractBatchEntitySelectFetchInitializer.java | 51 ++++++++++++++----- ...nsideEmbeddableSelectFetchInitializer.java | 1 + .../BatchEntitySelectFetchInitializer.java | 6 +++ ...nitializeEntitySelectFetchInitializer.java | 28 ++-------- 4 files changed, 48 insertions(+), 38 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/AbstractBatchEntitySelectFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/AbstractBatchEntitySelectFetchInitializer.java index 544947c37c..561157cf5a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/AbstractBatchEntitySelectFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/AbstractBatchEntitySelectFetchInitializer.java @@ -35,6 +35,8 @@ public abstract class AbstractBatchEntitySelectFetchInitializer extends Abstract protected Object entityInstance; protected EntityKey entityKey; + protected State state = State.UNINITIALIZED; + public AbstractBatchEntitySelectFetchInitializer( FetchParentAccess parentAccess, ToOneAttributeMapping referencedModelPart, @@ -61,20 +63,6 @@ public abstract class AbstractBatchEntitySelectFetchInitializer extends Abstract @Override public void resolveKey(RowProcessingState rowProcessingState) { - final Object entityIdentifier = identifierAssembler.assemble( rowProcessingState ); - if ( entityIdentifier == null ) { - return; - } - entityKey = new EntityKey( entityIdentifier, concreteDescriptor ); - - rowProcessingState.getSession().getPersistenceContext() - .getBatchFetchQueue().addBatchLoadableEntityKey( entityKey ); - - registerResolutionListener(); - } - - @Override - public void resolveInstance(RowProcessingState rowProcessingState) { } @Override @@ -83,10 +71,38 @@ public abstract class AbstractBatchEntitySelectFetchInitializer extends Abstract protected abstract void registerResolutionListener(); + protected void resolveKey( + RowProcessingState rowProcessingState, + ToOneAttributeMapping referencedModelPart, + FetchParentAccess parentAccess) { + if ( state != State.UNINITIALIZED ) { + return; + } + if ( !isAttributeAssignableToConcreteDescriptor( parentAccess, referencedModelPart ) ) { + state = State.MISSING; + return; + } + + final Object entityIdentifier = identifierAssembler.assemble( rowProcessingState ); + if ( entityIdentifier == null ) { + state = State.MISSING; + } + else { + entityKey = new EntityKey( entityIdentifier, concreteDescriptor ); + + state = State.KEY_RESOLVED; + + rowProcessingState.getSession().getPersistenceContext() + .getBatchFetchQueue().addBatchLoadableEntityKey( entityKey ); + registerResolutionListener(); + } + } + @Override public void finishUpRow(RowProcessingState rowProcessingState) { entityInstance = null; entityKey = null; + state = State.UNINITIALIZED; clearResolutionListeners(); } @@ -154,4 +170,11 @@ public abstract class AbstractBatchEntitySelectFetchInitializer extends Abstract return concreteDescriptor; } + enum State { + UNINITIALIZED, + MISSING, + KEY_RESOLVED, + INITIALIZED + } + } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntityInsideEmbeddableSelectFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntityInsideEmbeddableSelectFetchInitializer.java index 39ec075594..f4b8649280 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntityInsideEmbeddableSelectFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntityInsideEmbeddableSelectFetchInitializer.java @@ -63,6 +63,7 @@ public class BatchEntityInsideEmbeddableSelectFetchInitializer extends AbstractB @Override public void resolveInstance(RowProcessingState rowProcessingState) { + resolveKey( rowProcessingState, referencedModelPart, parentAccess ); if ( entityKey == null ) { return; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntitySelectFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntitySelectFetchInitializer.java index 439f40d64a..4f6797e4bb 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntitySelectFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntitySelectFetchInitializer.java @@ -23,6 +23,7 @@ import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.results.graph.DomainResultAssembler; import org.hibernate.sql.results.graph.FetchParentAccess; import org.hibernate.sql.results.graph.entity.EntityInitializer; +import org.hibernate.sql.results.jdbc.spi.RowProcessingState; public class BatchEntitySelectFetchInitializer extends AbstractBatchEntitySelectFetchInitializer { private Map> toBatchLoad; @@ -36,6 +37,11 @@ public class BatchEntitySelectFetchInitializer extends AbstractBatchEntitySelect super( parentAccess, referencedModelPart, fetchedNavigable, concreteDescriptor, identifierAssembler ); } + @Override + public void resolveInstance(RowProcessingState rowProcessingState) { + resolveKey( rowProcessingState, referencedModelPart, parentAccess ); + } + @Override protected void registerResolutionListener() { parentAccess.registerResolutionListener( parentInstance -> { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchInitializeEntitySelectFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchInitializeEntitySelectFetchInitializer.java index 3715943a0c..e738d63b3a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchInitializeEntitySelectFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchInitializeEntitySelectFetchInitializer.java @@ -28,7 +28,7 @@ import org.hibernate.sql.results.jdbc.spi.RowProcessingState; public class BatchInitializeEntitySelectFetchInitializer extends AbstractBatchEntitySelectFetchInitializer { private final Set toBatchLoad = new HashSet<>(); - private State state = State.UNINITIALIZED; + public BatchInitializeEntitySelectFetchInitializer( FetchParentAccess parentAccess, @@ -44,18 +44,11 @@ public class BatchInitializeEntitySelectFetchInitializer extends AbstractBatchEn // No-op, because we resolve a proxy } - @Override - public void resolveKey(RowProcessingState rowProcessingState) { - if ( state != State.UNINITIALIZED ) { - return; - } - super.resolveKey( rowProcessingState ); - state = entityKey == null ? State.MISSING : State.KEY_RESOLVED; - } - @Override public void resolveInstance(RowProcessingState rowProcessingState) { - if ( state != State.KEY_RESOLVED ) { + resolveKey( rowProcessingState, referencedModelPart, parentAccess ); + + if ( entityKey == null ) { return; } @@ -87,12 +80,6 @@ public class BatchInitializeEntitySelectFetchInitializer extends AbstractBatchEn return state == State.INITIALIZED; } - @Override - public void finishUpRow(RowProcessingState rowProcessingState) { - super.finishUpRow( rowProcessingState ); - state = State.UNINITIALIZED; - } - @Override public void endLoading(ExecutionContext context) { final SharedSessionContractImplementor session = context.getSession(); @@ -107,11 +94,4 @@ public class BatchInitializeEntitySelectFetchInitializer extends AbstractBatchEn return "BatchInitializeEntitySelectFetchInitializer(" + LoggingHelper.toLoggableString( getNavigablePath() ) + ")"; } - enum State { - UNINITIALIZED, - MISSING, - KEY_RESOLVED, - INITIALIZED - } - }