From 0d20cea0b33a179276d203ae2e8c6285153febcc Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Wed, 23 Nov 2022 19:10:01 +0100 Subject: [PATCH] HHH-15713 UnknownTableReferenceException on @ElementCollection of @Embeddable containing a @MayToOne with a @ManyToMany --- .../hibernate/engine/spi/SubselectFetch.java | 53 +++++++++++++------ .../entity/AbstractEntityInitializer.java | 4 +- .../graph/entity/EntityInitializer.java | 4 ++ .../internal/EntityResultInitializer.java | 5 ++ 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SubselectFetch.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SubselectFetch.java index 8c62bf4436..97ae1ad86c 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SubselectFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SubselectFetch.java @@ -19,6 +19,7 @@ import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.exec.spi.JdbcParameterBindings; +import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.entity.LoadingEntityEntry; /** @@ -104,7 +105,7 @@ public class SubselectFetch { return new StandardRegistrationHandler( batchFetchQueue, - sqlAst.getQuerySpec(), + sqlAst, tableGroup, jdbcParameters, jdbcParameterBindings @@ -137,7 +138,7 @@ public class SubselectFetch { public static class StandardRegistrationHandler implements RegistrationHandler { private final BatchFetchQueue batchFetchQueue; - private final QuerySpec loadingSqlAst; + private final SelectStatement loadingSqlAst; private final TableGroup ownerTableGroup; private final List loadingJdbcParameters; private final JdbcParameterBindings loadingJdbcParameterBindings; @@ -145,7 +146,7 @@ public class SubselectFetch { private StandardRegistrationHandler( BatchFetchQueue batchFetchQueue, - QuerySpec loadingSqlAst, + SelectStatement loadingSqlAst, TableGroup ownerTableGroup, List loadingJdbcParameters, JdbcParameterBindings loadingJdbcParameterBindings) { @@ -160,19 +161,39 @@ public class SubselectFetch { if ( !entry.getDescriptor().hasSubselectLoadableCollections() ) { return; } - final SubselectFetch subselectFetch = subselectFetches.computeIfAbsent( - entry.getEntityInitializer().getNavigablePath(), - navigablePath -> new SubselectFetch( - null, - loadingSqlAst, - ownerTableGroup, - loadingJdbcParameters, - loadingJdbcParameterBindings, - new HashSet<>() - ) - ); - subselectFetch.resultingEntityKeys.add( key ); - batchFetchQueue.addSubselect( key, subselectFetch ); + + if ( shouldAddSubselectFetch( entry ) ) { + final SubselectFetch subselectFetch = subselectFetches.computeIfAbsent( + entry.getEntityInitializer().getNavigablePath(), + navigablePath -> new SubselectFetch( + null, + loadingSqlAst.getQuerySpec(), + ownerTableGroup, + loadingJdbcParameters, + loadingJdbcParameterBindings, + new HashSet<>() + ) + ); + subselectFetch.resultingEntityKeys.add( key ); + batchFetchQueue.addSubselect( key, subselectFetch ); + } + } + + private boolean shouldAddSubselectFetch(LoadingEntityEntry entry) { + if ( entry.getEntityInitializer().isEntityResultInitializer() ) { + return true; + } + + final NavigablePath entityInitializerParent = entry.getEntityInitializer().getNavigablePath().getParent(); + + // We want to add only the collections of the loading entities + for ( DomainResult domainResult : loadingSqlAst.getDomainResultDescriptors() ) { + if ( domainResult.getNavigablePath().equals( entityInitializerParent ) ) { + return true; + } + } + + return false; } } } 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 73003dcbe9..55a7bd9775 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 @@ -464,7 +464,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces .getEntityInstance(); if ( proxy != null && ( proxy instanceof MapProxy || entityDescriptor.getJavaType().getJavaTypeClass().isInstance( proxy ) ) ) { - if ( this instanceof EntityResultInitializer && entityInstanceFromExecutionContext != null ) { + if ( this.isEntityResultInitializer() && entityInstanceFromExecutionContext != null ) { this.entityInstance = entityInstanceFromExecutionContext; registerLoadingEntity( rowProcessingState, entityInstance ); } @@ -477,7 +477,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces if ( existingEntity != null ) { this.entityInstance = existingEntity; } - else if ( this instanceof EntityResultInitializer && entityInstanceFromExecutionContext != null ) { + else if ( this.isEntityResultInitializer() && entityInstanceFromExecutionContext != null ) { this.entityInstance = entityInstanceFromExecutionContext; registerLoadingEntity( rowProcessingState, entityInstance ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/EntityInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/EntityInitializer.java index ac78d6f33c..a3413e796e 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/EntityInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/EntityInitializer.java @@ -60,4 +60,8 @@ public interface EntityInitializer extends FetchParentAccess { return this; } + + default boolean isEntityResultInitializer() { + return false; + } } 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 06ff5c46f2..529d8db7fc 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 @@ -56,4 +56,9 @@ public class EntityResultInitializer extends AbstractEntityInitializer { public String toString() { return CONCRETE_NAME + "(" + getNavigablePath() + ")"; } + + @Override + public boolean isEntityResultInitializer() { + return true; + } }