HHH-16077 - Added named native queries cannot specify result-class

This commit is contained in:
Steve Ebersole 2023-01-23 21:32:31 -06:00
parent e7b2f9b121
commit 6e442aaed5
4 changed files with 30 additions and 15 deletions

View File

@ -8,9 +8,13 @@ package org.hibernate.query.results.implicit;
import java.util.function.BiFunction;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.query.results.ResultBuilder;
import org.hibernate.query.results.ResultSetMappingSqlSelection;
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.basic.BasicResult;
@ -39,23 +43,34 @@ public class ImplicitResultClassBuilder implements ResultBuilder {
int resultPosition,
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
DomainResultCreationState domainResultCreationState) {
final MappingMetamodelImplementor mappingMetamodel = domainResultCreationState.getSqlAstCreationState()
.getCreationContext()
.getMappingMetamodel();
final TypeConfiguration typeConfiguration = mappingMetamodel.getTypeConfiguration();
final int jdbcResultPosition = resultPosition + 1;
assert resultPosition == 0;
final BasicType<Object> basicType = jdbcResultsMetadata.resolveType(
final SessionFactoryImplementor sessionFactory = domainResultCreationState.getSqlAstCreationState()
.getCreationContext()
.getSessionFactory();
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
final SqlExpressionResolver sqlExpressionResolver = domainResultCreationState.getSqlAstCreationState().getSqlExpressionResolver();
final int jdbcResultPosition = 1;
final String columnName = jdbcResultsMetadata.resolveColumnName( jdbcResultPosition );
final BasicType<?> basicType = jdbcResultsMetadata.resolveType(
jdbcResultPosition,
typeConfiguration.getJavaTypeRegistry().resolveDescriptor( suppliedResultClass ),
typeConfiguration
);
return new BasicResult<>(
resultPosition,
jdbcResultsMetadata.resolveColumnName( jdbcResultPosition ),
basicType
final SqlSelection selection = sqlExpressionResolver.resolveSqlSelection(
sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( columnName ),
(state) -> new ResultSetMappingSqlSelection( resultPosition, (BasicValuedMapping) basicType )
),
basicType.getMappedJavaType(),
null,
typeConfiguration
);
return new BasicResult<>( selection.getValuesArrayPosition(), columnName, basicType );
}
@Override

View File

@ -12,7 +12,6 @@ import java.util.Set;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.query.named.AbstractNamedQueryMemento;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
@ -128,7 +127,7 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
originalSqlString,
resultSetMappingName,
resultSetMappingClass,
CollectionHelper.makeCopy( querySpaces ),
querySpaces,
getCacheable(),
getCacheRegion(),
getCacheMode(),

View File

@ -856,7 +856,7 @@ public class NativeQueryImpl<R>
}
public void addResultTypeClass(Class<?> resultClass) {
assert CollectionHelper.isEmpty( resultSetMapping.getResultBuilders() );
assert resultSetMapping.getNumberOfResultBuilders() == 0;
registerBuilder( Builders.resultClassBuilder( resultClass, getSessionFactory() ) );
}

View File

@ -71,7 +71,8 @@ public class NativeQuerySchemaPlaceholderTest {
scope.inTransaction(
session -> {
NativeQueryImplementor<Long> nativeQuery = session.createNativeQuery(
"select id from {h-schema}TestEntity", Long.class
"select id from {h-schema}TestEntity",
Long.class
);
List<Long> results = nativeQuery.list();
assertThat( results.get( 0 ), is( 1l ) );