HHH-15346 @ManyToOne associations not loaded correctly with default EAGER and batch fetch property set

This commit is contained in:
Andrea Boriero 2022-06-22 19:03:12 +02:00 committed by Andrea Boriero
parent a70150fe2e
commit f5be0e1f07

View File

@ -6,7 +6,9 @@
*/ */
package org.hibernate.sql.results.graph.entity.internal; package org.hibernate.sql.results.graph.entity.internal;
import java.util.LinkedHashMap; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -47,7 +49,7 @@ public class BatchEntitySelectFetchInitializer extends AbstractFetchParentAccess
protected Object entityInstance; protected Object entityInstance;
private EntityKey entityKey; private EntityKey entityKey;
private Map<EntityKey, Object> toBatchLoad = new LinkedHashMap<>(); private Map<EntityKey, List<Object>> toBatchLoad = new HashMap<>();
private boolean isInitialized; private boolean isInitialized;
@ -76,7 +78,6 @@ public NavigablePath getNavigablePath() {
@Override @Override
public void resolveKey(RowProcessingState rowProcessingState) { public void resolveKey(RowProcessingState rowProcessingState) {
} }
@Override @Override
@ -147,7 +148,13 @@ public void initializeInstance(RowProcessingState rowProcessingState) {
} }
persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey( entityKey ); persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey( entityKey );
toBatchLoad.put( entityKey, parentAccess.getInitializedInstance() ); List<Object> objects = toBatchLoad.get( entityKey );
if ( objects == null ) {
objects = new ArrayList<>();
toBatchLoad.put( entityKey, objects );
}
objects.add( parentAccess.getInitializedInstance() );
isInitialized = true; isInitialized = true;
} }
@ -215,15 +222,17 @@ public String toString() {
@Override @Override
public void endLoading(ExecutionContext context) { public void endLoading(ExecutionContext context) {
final int propertyIndex = ( (UniqueKeyLoadable) ( (AbstractEntityInitializer) parentAccess ).getEntityDescriptor() )
.getPropertyIndex( referencedModelPart.getPartName() );
toBatchLoad.forEach( toBatchLoad.forEach(
(entityKey, parentInstance) -> { (entityKey, parentInstances) -> {
final Object instance = context.getSession().internalLoad( final Object instance = context.getSession().internalLoad(
entityKey.getEntityName(), entityKey.getEntityName(),
entityKey.getIdentifier(), entityKey.getIdentifier(),
true, true,
referencedModelPart.isInternalLoadNullable() referencedModelPart.isInternalLoadNullable()
); );
if ( instance != null ) { for ( Object parentInstance : parentInstances ) {
( (AbstractEntityPersister) referencedModelPart.getDeclaringType() ).setPropertyValue( ( (AbstractEntityPersister) referencedModelPart.getDeclaringType() ).setPropertyValue(
parentInstance, parentInstance,
referencedModelPart.getPartName(), referencedModelPart.getPartName(),
@ -232,8 +241,6 @@ public void endLoading(ExecutionContext context) {
final EntityEntry entry = context.getSession() final EntityEntry entry = context.getSession()
.getPersistenceContext() .getPersistenceContext()
.getEntry( parentInstance ); .getEntry( parentInstance );
final int propertyIndex = ( (UniqueKeyLoadable) ( (AbstractEntityInitializer) parentAccess ).getEntityDescriptor() ).getPropertyIndex(
referencedModelPart.getPartName() );
if ( entry != null ) { if ( entry != null ) {
final Object[] loadedState = entry.getLoadedState(); final Object[] loadedState = entry.getLoadedState();
if ( loadedState != null ) { if ( loadedState != null ) {