diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java index fc4f024dc86f..f1ec3fff253e 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java @@ -969,7 +969,8 @@ else if ( List.class.equals( resultClass ) ) { query.setTupleTransformer( NativeQueryListTransformer.INSTANCE ); } else if ( getFactory().getMappingMetamodel().isEntityClass( resultClass ) ) { - query.addEntity( resultClass, LockMode.READ ); + // use null as tableAlias to identify it as implicit + query.addEntity( null, resultClass, LockMode.READ ); } else if ( resultClass != Object.class && resultClass != Object[].class ) { if ( isClass( resultClass ) && !hasJavaTypeDescriptor( resultClass ) ) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMapping.java b/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMapping.java index 433d6e8cf40f..f00885c651d2 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMapping.java @@ -77,6 +77,11 @@ public interface ResultSetMapping extends JdbcValuesMappingProducer { */ void addResultBuilder(ResultBuilder resultBuilder); + /** + * Remove a builder + */ + void removeResultBuilder(ResultBuilder resultBuilder); + /** * Add a legacy fetch builder */ diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMappingImpl.java index 8742d54ca3f1..f360966ac74a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMappingImpl.java @@ -137,6 +137,11 @@ public void addResultBuilder(ResultBuilder resultBuilder) { resultBuilders.add( resultBuilder ); } + @Override + public void removeResultBuilder(ResultBuilder resultBuilder) { + resultBuilders.remove( resultBuilder ); + } + @Override public void addLegacyFetchBuilder(DynamicFetchBuilderLegacy fetchBuilder) { final Map existingFetchBuildersByOwner; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java index 691252daa6ad..6d75a33677c1 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java @@ -942,6 +942,23 @@ public NativeQueryImplementor addScalar(int position, Class type) { } protected NativeQueryImplementor registerBuilder(ResultBuilder builder) { + // remove implicit ResultBuilder if explicit one provided + if ( builder instanceof DynamicResultBuilderEntityCalculated dynamicBuilder ) { + ResultBuilder implicitResultBuilder = null; + for ( ResultBuilder existing : resultSetMapping.getResultBuilders() ) { + if ( existing instanceof DynamicResultBuilderEntityCalculated existingDynamicBuilder ) { + if ( existingDynamicBuilder.getTableAlias() == null // implicit one doesn't have tableAlias + && existingDynamicBuilder.getNavigablePath().equals( dynamicBuilder.getNavigablePath() ) + && existingDynamicBuilder.getEntityMapping().equals( dynamicBuilder.getEntityMapping() ) ) { + implicitResultBuilder = existingDynamicBuilder; + break; + } + } + } + if ( implicitResultBuilder != null ) { + resultSetMapping.removeResultBuilder( implicitResultBuilder ); + } + } resultSetMapping.addResultBuilder( builder ); return this; }