From 6b4ba438c2f6b1540f1408592d6f5c6b06a00742 Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Wed, 18 Sep 2024 11:58:44 +0800 Subject: [PATCH] HHH-18629 Fix inconsistent column alias generated while result class is used for placeholder --- .../internal/AbstractSharedSessionContract.java | 3 ++- .../query/results/ResultSetMapping.java | 5 +++++ .../query/results/ResultSetMappingImpl.java | 5 +++++ .../query/sql/internal/NativeQueryImpl.java | 17 +++++++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) 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; }