HHH-16743 StackOverflowError when loading a ManyToOne whith @Proxy(lazy=false)

This commit is contained in:
Andrea Boriero 2023-06-13 10:00:37 +02:00 committed by Andrea Boriero
parent faf1536ccb
commit 8cc568ce1b
1 changed files with 23 additions and 4 deletions

View File

@ -19,6 +19,10 @@ import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.embeddable.EmbeddableInitializer;
import static org.hibernate.sql.results.graph.entity.internal.EntitySelectFetchInitializerBuilder.BatchMode.BATCH_INITIALIZE;
import static org.hibernate.sql.results.graph.entity.internal.EntitySelectFetchInitializerBuilder.BatchMode.BATCH_LOAD;
import static org.hibernate.sql.results.graph.entity.internal.EntitySelectFetchInitializerBuilder.BatchMode.NONE;
public class EntitySelectFetchInitializerBuilder {
public static AbstractFetchParentAccess createInitializer(
@ -94,10 +98,13 @@ public class EntitySelectFetchInitializerBuilder {
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
if ( !entityPersister.isBatchLoadable() || creationState.isScrollResult() ) {
return BatchMode.NONE;
return NONE;
}
else if ( creationState.isDynamicInstantiation() ) {
return BatchMode.BATCH_INITIALIZE;
if ( canBatchInitializeBeUsed( entityPersister ) ) {
return BatchMode.BATCH_INITIALIZE;
}
return NONE;
}
while ( parentAccess.isEmbeddableInitializer() ) {
final EmbeddableInitializer embeddableInitializer = parentAccess.asEmbeddableInitializer();
@ -124,10 +131,22 @@ public class EntitySelectFetchInitializerBuilder {
if ( cacheAccess != null ) {
// Do batch initialization instead of batch loading if the parent entity is cacheable
// to avoid putting entity state into the cache at a point when the association is not yet set
return BatchMode.BATCH_INITIALIZE;
if ( canBatchInitializeBeUsed( entityPersister ) ) {
return BATCH_INITIALIZE;
}
return NONE;
}
}
return BatchMode.BATCH_LOAD;
return BATCH_LOAD;
}
private static boolean canBatchInitializeBeUsed(EntityPersister entityPersister) {
if ( entityPersister.getRepresentationStrategy().getProxyFactory() == null
&& entityPersister.hasSubclasses() ) {
// We cannot neither create a proxy nor instantiate the entity because we don't know the concrete type
return false;
}
return true;
}
enum BatchMode {