From 3af8b6235a706d12b8dcf5c94ba38f91389ac833 Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Fri, 13 Jul 2018 14:45:11 -0700 Subject: [PATCH] HHH-12802 : Hibernate does not thrown an exception when more than entity is loaded with the same ID (cherry picked from commit 926ad5a13335ae2b6408c68203bee5198fa8c4d1) --- .../AbstractLoadPlanBasedEntityLoader.java | 29 ++++++++++++++++--- .../BatchingLoadQueryDetailsFactory.java | 4 +-- .../exec/internal/EntityLoadQueryDetails.java | 6 ++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java index 05a613203b..2fb8af6e09 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java @@ -49,7 +49,7 @@ public abstract class AbstractLoadPlanBasedEntityLoader extends AbstractLoadPlan private final Type uniqueKeyType; private final String entityName; - private final LoadQueryDetails staticLoadQuery; + private final EntityLoadQueryDetails staticLoadQuery; public AbstractLoadPlanBasedEntityLoader( OuterJoinLoadable entityPersister, @@ -189,7 +189,7 @@ public abstract class AbstractLoadPlanBasedEntityLoader extends AbstractLoadPlan false, null ); - result = extractEntityResult( results ); + result = extractEntityResult( results, id ); } catch ( SQLException sqle ) { throw session.getJdbcServices().getSqlExceptionHelper().convert( @@ -208,14 +208,22 @@ public abstract class AbstractLoadPlanBasedEntityLoader extends AbstractLoadPlan return result; } + /** + * @deprecated {@link #extractEntityResult(List, Serializable)} should be used instead. + */ + @Deprecated protected Object extractEntityResult(List results) { + return extractEntityResult( results, null ); + } + + protected Object extractEntityResult(List results, Serializable id) { if ( results.size() == 0 ) { return null; } else if ( results.size() == 1 ) { return results.get( 0 ); } - else { + else if ( staticLoadQuery.hasCollectionInitializers() ) { final Object row = results.get( 0 ); if ( row.getClass().isArray() ) { // the logical type of the result list is List. See if the contained @@ -230,7 +238,20 @@ public abstract class AbstractLoadPlanBasedEntityLoader extends AbstractLoadPlan } } - throw new HibernateException( "Unable to interpret given query results in terms of a load-entity query" ); + if ( id == null ) { + throw new HibernateException( + "Unable to interpret given query results in terms of a load-entity query for " + + entityName + ); + } + else { + throw new HibernateException( + "More than one row with the given identifier was found: " + + id + + ", for class: " + + entityName + ); + } } protected int[] getNamedParameterLocs(String name) { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/BatchingLoadQueryDetailsFactory.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/BatchingLoadQueryDetailsFactory.java index 6803b70997..3b03f72d9c 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/BatchingLoadQueryDetailsFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/BatchingLoadQueryDetailsFactory.java @@ -41,7 +41,7 @@ public class BatchingLoadQueryDetailsFactory { * * @return The EntityLoadQueryDetails */ - public LoadQueryDetails makeEntityLoadQueryDetails( + public EntityLoadQueryDetails makeEntityLoadQueryDetails( LoadPlan loadPlan, String[] keyColumnNames, QueryBuildingParameters buildingParameters, @@ -76,7 +76,7 @@ public class BatchingLoadQueryDetailsFactory { * that add additional joins here) * @return The EntityLoadQueryDetails */ - public LoadQueryDetails makeEntityLoadQueryDetails( + public EntityLoadQueryDetails makeEntityLoadQueryDetails( EntityLoadQueryDetails entityLoadQueryDetailsTemplate, QueryBuildingParameters buildingParameters) { return new EntityLoadQueryDetails( diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/EntityLoadQueryDetails.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/EntityLoadQueryDetails.java index f7052d5ac8..2495fb7f2e 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/EntityLoadQueryDetails.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/EntityLoadQueryDetails.java @@ -14,6 +14,7 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.CoreLogging; +import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.loader.plan.exec.process.internal.AbstractRowReader; import org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl; import org.hibernate.loader.plan.exec.process.internal.EntityReturnReader; @@ -104,6 +105,11 @@ public class EntityLoadQueryDetails extends AbstractLoadQueryDetails { generate(); } + public boolean hasCollectionInitializers() { + return CollectionHelper.isNotEmpty( readerCollector.getArrayReferenceInitializers() ) || + CollectionHelper.isNotEmpty( readerCollector.getNonArrayCollectionReferenceInitializers() ); + } + private EntityReturn getRootEntityReturn() { return (EntityReturn) getRootReturn(); }