Work on column alias resolving

This commit is contained in:
Christian Beikov 2020-11-24 19:15:25 +01:00
parent 6643e9f4bc
commit 7bf5117a02
13 changed files with 213 additions and 233 deletions

View File

@ -6,6 +6,8 @@
*/
package org.hibernate;
import java.util.function.BiFunction;
/**
* Hibernate often deals with compound names/paths. This interface defines a standard way of interacting with them
*
@ -21,4 +23,15 @@ public interface DotIdentifierSequence {
default boolean isRoot() {
return getParent() == null;
}
default <T> T resolve(T base, BiFunction<T, String, T> resolver) {
final T result;
if ( getParent() == null ) {
result = base;
}
else {
result = resolver.apply( getParent().resolve( base, resolver ), getLocalName() );
}
return result;
}
}

View File

@ -26,11 +26,14 @@ import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryScalarReturnType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmResultSetMappingType;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.internal.FetchMementoBasicStandard;
import org.hibernate.query.internal.FetchMementoHbmStandard;
import org.hibernate.query.internal.FetchMementoHbmStandard.FetchParentMemento;
import org.hibernate.query.internal.ModelPartResultMementoBasicImpl;
@ -538,9 +541,10 @@ public class HbmResultSetMappingDescriptor implements NamedResultSetMappingDescr
);
}
navigablePath = fetchParentMemento.getNavigablePath().append( propertyPathParts[ i ] );
fetchable = (Fetchable) ( (FetchableContainer) fetchable ).findSubPart( propertyPathParts[i], null );
}
return new FetchMementoHbmStandard( navigablePath, fetchParentMemento, fetchable );
return new FetchMementoBasicStandard( navigablePath, (BasicValuedModelPart) fetchable, columnAliases.get( 0 ) );
}
@Override

View File

@ -28,7 +28,7 @@ import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.internal.FetchMementoJpa;
import org.hibernate.query.internal.FetchMementoBasicStandard;
import org.hibernate.query.internal.ModelPartResultMementoBasicImpl;
import org.hibernate.query.internal.NamedResultSetMappingMementoImpl;
import org.hibernate.query.internal.ResultMementoBasicStandard;
@ -41,6 +41,7 @@ import org.hibernate.query.named.NamedResultSetMappingMemento;
import org.hibernate.query.named.ResultMemento;
import org.hibernate.query.named.ResultMementoBasic;
import org.hibernate.query.named.ResultMementoInstantiation.ArgumentMemento;
import org.hibernate.query.results.complete.CompleteResultBuilderBasicModelPart;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
@ -395,7 +396,20 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
@Override
public FetchMemento resolve(ResultSetMappingResolutionContext resolutionContext) {
return new FetchMementoJpa( navigablePath, relativeFetchPath );
final RuntimeMetamodels runtimeMetamodels = resolutionContext.getSessionFactory().getRuntimeMetamodels();
final EntityMappingType entityMapping = runtimeMetamodels.getEntityMappingType( entityName );
final ModelPart subPart = entityMapping.resolveSubPart( navigablePath );
if ( subPart instanceof BasicValuedModelPart ) {
assert columnNames.size() == 1;
final BasicValuedModelPart basicPart = (BasicValuedModelPart) subPart;
return new FetchMementoBasicStandard( navigablePath, basicPart, columnNames.get( 0 ) );
}
throw new NotYetImplementedFor6Exception(
"Only support for basic-valued model-parts have been implemented : " + relativeFetchPath
+ " [" + subPart + "]"
);
}
}
}

View File

@ -8,6 +8,7 @@ package org.hibernate.metamodel.mapping;
import java.util.function.Consumer;
import org.hibernate.DotIdentifierSequence;
import org.hibernate.boot.spi.SessionFactoryOptions;
/**
@ -33,6 +34,10 @@ public interface Queryable extends ModelPart {
*/
ModelPart findSubPart(String name, EntityMappingType treatTargetType);
default ModelPart resolveSubPart(DotIdentifierSequence path) {
return path.resolve( (ModelPart) this, (part, name) -> ( (Queryable) part ).findSubPart( name, null ) );
}
/**
* For an entity, this form allows for Hibernate's "implicit treat" support -
* meaning it should find a sub-part whether defined on the entity or one of its sub-types.

View File

@ -219,6 +219,7 @@ import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.sql.results.graph.entity.internal.EntityResultImpl;
import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.tuple.GenerationTiming;
@ -6751,11 +6752,14 @@ public abstract class AbstractEntityPersister
public void visitKeyFetchables(
Consumer<Fetchable> fetchableConsumer,
EntityMappingType treatTargetType) {
// if ( getIdentifierMapping() instanceof FetchableContainer ) {
// final EntityIdentifierMapping identifierMapping = getIdentifierMapping();
// if ( identifierMapping instanceof FetchableContainer ) {
// // essentially means the entity has a composite id - ask the embeddable to visit its fetchables
// ( (FetchableContainer) getIdentifierMapping() ).visitFetchables( fetchableConsumer, treatTargetType );
// ( (FetchableContainer) identifierMapping ).visitFetchables( fetchableConsumer, treatTargetType );
// }
// else {
// fetchableConsumer.accept( (Fetchable) identifierMapping );
// }
// otherwise, nothing to do
}
@Override

View File

@ -1,58 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.internal;
import java.util.function.BiFunction;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.results.FetchBuilder;
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
/**
* @author Steve Ebersole
*/
public class FetchBuilderJpa implements FetchBuilder {
private final NavigablePath navigablePath;
private final String attributePath;
public FetchBuilderJpa(NavigablePath navigablePath, String attributePath) {
this.navigablePath = navigablePath;
this.attributePath = attributePath;
}
@Override
public Fetch buildFetch(
FetchParent parent,
NavigablePath fetchPath,
JdbcValuesMetadata jdbcResultsMetadata,
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
DomainResultCreationState domainResultCreationState) {
assert fetchPath.equals( navigablePath );
assert fetchPath.getFullPath().endsWith( attributePath );
final FetchableContainer container = parent.getReferencedMappingContainer();
final Fetchable subPart = (Fetchable) container.findSubPart( fetchPath.getLocalName(), null );
return subPart.generateFetch(
parent,
fetchPath,
FetchTiming.IMMEDIATE,
true,
LockMode.READ,
null,
domainResultCreationState
);
}
}

View File

@ -1,49 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.internal;
import java.util.function.Consumer;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.named.FetchMemento;
import org.hibernate.query.results.FetchBuilder;
/**
* @author Steve Ebersole
*/
public class FetchMementoJpa implements FetchMemento {
private final NavigablePath fetchPath;
private final String attributePath;
public FetchMementoJpa(NavigablePath fetchPath, String attributePath) {
this.fetchPath = fetchPath;
this.attributePath = attributePath;
}
@Override
public FetchBuilder resolve(
Parent parent,
Consumer<String> querySpaceConsumer,
ResultSetMappingResolutionContext context) {
final String[] names = attributePath.split( "\\." );
NavigablePath fetchPath = parent.getNavigablePath();
//noinspection ForLoopReplaceableByForEach
for ( int i = 0; i < names.length; i++ ) {
fetchPath = fetchPath.append( names[ i ] );
}
return new FetchBuilderJpa( fetchPath, attributePath );
}
@Override
public NavigablePath getNavigablePath() {
return fetchPath;
}
}

View File

@ -34,6 +34,7 @@ import org.hibernate.query.results.implicit.ImplicitFetchBuilder;
import org.hibernate.query.results.implicit.ImplicitFetchBuilderBasic;
import org.hibernate.query.results.implicit.ImplicitFetchBuilderEmbeddable;
import org.hibernate.query.results.implicit.ImplicitModelPartResultBuilderEntity;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
@ -243,7 +244,10 @@ public class Builders {
return new ImplicitModelPartResultBuilderEntity( entityMappingType );
}
public static ImplicitFetchBuilder implicitFetchBuilder(NavigablePath fetchPath, Fetchable fetchable) {
public static ImplicitFetchBuilder implicitFetchBuilder(
NavigablePath fetchPath,
Fetchable fetchable,
DomainResultCreationState creationState) {
if ( fetchable instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basicValuedFetchable = (BasicValuedModelPart) fetchable;
return new ImplicitFetchBuilderBasic( fetchPath, basicValuedFetchable );
@ -251,7 +255,7 @@ public class Builders {
if ( fetchable instanceof EmbeddableValuedFetchable ) {
final EmbeddableValuedFetchable embeddableValuedFetchable = (EmbeddableValuedFetchable) fetchable;
return new ImplicitFetchBuilderEmbeddable( fetchPath, embeddableValuedFetchable );
return new ImplicitFetchBuilderEmbeddable( fetchPath, embeddableValuedFetchable, creationState );
}
if ( fetchable instanceof EntityValuedFetchable ) {

View File

@ -20,7 +20,9 @@ import org.hibernate.internal.util.collections.Stack;
import org.hibernate.internal.util.collections.StandardStack;
import org.hibernate.metamodel.mapping.AssociationKey;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.internal.NonAggregatedIdentifierMappingImpl;
import org.hibernate.query.EntityIdentifierNavigablePath;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
@ -39,7 +41,9 @@ import org.hibernate.sql.results.ResultsLogger;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@ -113,10 +117,18 @@ public class DomainResultCreationStateImpl
return jdbcResultsMetadata;
}
public NavigablePath getCurrentRelativePath() {
return relativePathStack.getCurrent();
}
public void pushExplicitFetchMementoResolver(Function<String, FetchBuilder> resolver) {
fetchBuilderResolverStack.push( resolver );
}
public Function<String, FetchBuilder> getCurrentExplicitFetchMementoResolver() {
return fetchBuilderResolverStack.getCurrent();
}
public Function<String, FetchBuilder> popExplicitFetchMementoResolver() {
return fetchBuilderResolverStack.pop();
}
@ -299,75 +311,71 @@ public class DomainResultCreationStateImpl
final List<Fetch> fetches = CollectionHelper.arrayList( fetchableContainer.getNumberOfFetchables() );
final Consumer<Fetchable> fetchableConsumer = fetchable -> {
final String fetchableName = fetchable.getFetchableName();
final NavigablePath fetchPath = fetchParent.getNavigablePath().append( fetchableName );
final NavigablePath relativePath = relativePathStack.isEmpty()
? new NavigablePath( fetchableName )
: relativePathStack.getCurrent().append( fetchableName );
relativePathStack.push( relativePath );
try {
final FetchBuilder explicitFetchBuilder = fetchBuilderResolverStack
.getCurrent()
.apply( relativePath.getFullPath() );
final FetchBuilder fetchBuilder = explicitFetchBuilder != null
? explicitFetchBuilder
: Builders.implicitFetchBuilder( fetchPath, fetchable, this );
final Fetch fetch = fetchBuilder.buildFetch(
fetchParent,
fetchPath,
jdbcResultsMetadata,
(s, s2) -> {
throw new UnsupportedOperationException();
},
this
);
fetches.add( fetch );
}
finally {
relativePathStack.pop();
}
};
boolean previous = this.processingKeyFetches;
this.processingKeyFetches = true;
if ( fetchableContainer instanceof EntityValuedFetchable ) {
final EntityValuedFetchable entityValuedFetchable = (EntityValuedFetchable) fetchableContainer;
if ( fetchableContainer instanceof EntityValuedModelPart ) {
final EntityValuedModelPart entityValuedFetchable = (EntityValuedModelPart) fetchableContainer;
final EntityIdentifierMapping identifierMapping = entityValuedFetchable.getEntityMappingType().getIdentifierMapping();
relativePathStack.push(
new EntityIdentifierNavigablePath(
relativePathStack.getCurrent(),
attributeName( identifierMapping )
)
);
final boolean idClass = identifierMapping instanceof NonAggregatedIdentifierMappingImpl;
if ( idClass ) {
relativePathStack.push(
new EntityIdentifierNavigablePath(
relativePathStack.getCurrent(),
attributeName( identifierMapping )
)
);
}
try {
entityValuedFetchable.getEntityMappingType().visitKeyFetchables(
fetchable -> {
// depends whether these fetchables are the identifier mapping or
// the identifier sub-attribuates (if composite)
final String fetchableName = fetchable.getFetchableName();
final NavigablePath fetchPath = fetchParent.getNavigablePath().append( fetchableName );
final NavigablePath relativePath = relativePathStack.isEmpty()
? new NavigablePath( fetchableName )
: relativePathStack.getCurrent().append( fetchableName );
},
null
);
if ( identifierMapping instanceof FetchableContainer ) {
// essentially means the entity has a composite id - ask the embeddable to visit its fetchables
( (FetchableContainer) identifierMapping ).visitFetchables( fetchableConsumer, null );
}
else {
fetchableConsumer.accept( (Fetchable) identifierMapping );
}
}
finally {
this.processingKeyFetches = previous;
this.relativePathStack.pop();
if ( idClass ) {
this.relativePathStack.pop();
}
}
}
fetchableContainer.visitFetchables(
fetchable -> {
final String fetchableName = fetchable.getFetchableName();
final NavigablePath fetchPath = fetchParent.getNavigablePath().append( fetchableName );
final NavigablePath relativePath = relativePathStack.isEmpty()
? new NavigablePath( fetchableName )
: relativePathStack.getCurrent().append( fetchableName );
relativePathStack.push( relativePath );
try {
final FetchBuilder explicitFetchBuilder = fetchBuilderResolverStack
.getCurrent()
.apply( relativePath.getFullPath() );
final FetchBuilder fetchBuilder = explicitFetchBuilder != null
? explicitFetchBuilder
: Builders.implicitFetchBuilder( fetchPath, fetchable );
final Fetch fetch = fetchBuilder.buildFetch(
fetchParent,
fetchPath,
jdbcResultsMetadata,
(s, s2) -> {
throw new UnsupportedOperationException();
},
this
);
fetches.add( fetch );
}
finally {
relativePathStack.pop();
}
},
null
);
fetchableContainer.visitFetchables( fetchableConsumer, null );
return fetches;
}

View File

@ -30,19 +30,19 @@ public class CompleteResultBuilderEntityStandard implements CompleteResultBuilde
private final EntityMappingType entityDescriptor;
private final LockMode lockMode;
private final ResultBuilderBasicValued discriminatorResultBuilder;
private final HashMap<String, FetchBuilder> fetchBuilderMap;
private final HashMap<String, FetchBuilder> explicitFetchBuilderMap;
public CompleteResultBuilderEntityStandard(
NavigablePath navigablePath,
EntityMappingType entityDescriptor,
LockMode lockMode,
ResultBuilderBasicValued discriminatorResultBuilder,
HashMap<String, FetchBuilder> fetchBuilderMap) {
HashMap<String, FetchBuilder> explicitFetchBuilderMap) {
this.navigablePath = navigablePath;
this.entityDescriptor = entityDescriptor;
this.lockMode = lockMode;
this.discriminatorResultBuilder = discriminatorResultBuilder;
this.fetchBuilderMap = fetchBuilderMap;
this.explicitFetchBuilderMap = explicitFetchBuilderMap;
}
@Override
@ -62,41 +62,49 @@ public class CompleteResultBuilderEntityStandard implements CompleteResultBuilde
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
DomainResultCreationState domainResultCreationState) {
final DomainResultCreationStateImpl impl = ResultsHelper.impl( domainResultCreationState );
impl.disallowPositionalSelections();
// we just want it added to the registry
impl.getFromClauseAccess().resolveTableGroup(
navigablePath,
np -> entityDescriptor.createRootTableGroup(
navigablePath,
null,
false,
lockMode,
() -> predicate -> {},
impl,
impl.getCreationContext()
)
);
impl.pushExplicitFetchMementoResolver( explicitFetchBuilderMap::get );
final BasicResult<?> discriminatorResult;
if ( discriminatorResultBuilder != null ) {
discriminatorResult = discriminatorResultBuilder.buildResult(
jdbcResultsMetadata,
resultPosition,
legacyFetchResolver,
try {
// we just want it added to the registry
impl.getFromClauseAccess().resolveTableGroup(
navigablePath,
np -> entityDescriptor.createRootTableGroup(
navigablePath,
null,
false,
lockMode,
() -> predicate -> {},
impl,
impl.getCreationContext()
)
);
final BasicResult<?> discriminatorResult;
if ( discriminatorResultBuilder != null ) {
discriminatorResult = discriminatorResultBuilder.buildResult(
jdbcResultsMetadata,
resultPosition,
legacyFetchResolver,
domainResultCreationState
);
}
else {
discriminatorResult = null;
}
return new EntityResultImpl(
navigablePath,
entityDescriptor,
null,
lockMode,
discriminatorResult,
domainResultCreationState
);
}
else {
discriminatorResult = null;
finally {
impl.popExplicitFetchMementoResolver();
}
return new EntityResultImpl(
navigablePath,
entityDescriptor,
null,
lockMode,
discriminatorResult,
domainResultCreationState
);
}
}

View File

@ -11,6 +11,7 @@ import java.util.function.BiFunction;
import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.ConvertibleModelPart;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.results.DomainResultCreationStateImpl;
import org.hibernate.query.results.ResultsHelper;
@ -71,6 +72,14 @@ public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder {
.getTypeConfiguration()
);
final BasicValueConverter valueConverter;
if ( fetchable instanceof ConvertibleModelPart ) {
valueConverter = ( (ConvertibleModelPart) fetchable ).getValueConverter();
}
else {
valueConverter = null;
}
return new BasicFetch<>(
valuesArrayPosition,
parent,
@ -78,7 +87,7 @@ public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder {
fetchable,
// todo (6.0) - we don't know
true,
( (ConvertibleModelPart) fetchable ).getValueConverter(),
valueConverter,
FetchTiming.IMMEDIATE,
domainResultCreationState
);

View File

@ -6,12 +6,17 @@
*/
package org.hibernate.query.results.implicit;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchTiming;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.results.Builders;
import org.hibernate.query.results.DomainResultCreationStateImpl;
import org.hibernate.query.results.FetchBuilder;
import org.hibernate.query.results.SqlSelectionImpl;
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
import org.hibernate.sql.ast.SqlAstJoinType;
@ -35,12 +40,36 @@ import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnRefere
public class ImplicitFetchBuilderEmbeddable implements ImplicitFetchBuilder {
private final NavigablePath fetchPath;
private final EmbeddableValuedFetchable fetchable;
private final Map<NavigablePath, FetchBuilder> fetchBuilders;
public ImplicitFetchBuilderEmbeddable(
NavigablePath fetchPath,
EmbeddableValuedFetchable fetchable) {
EmbeddableValuedFetchable fetchable,
DomainResultCreationState creationState) {
this.fetchPath = fetchPath;
this.fetchable = fetchable;
final DomainResultCreationStateImpl creationStateImpl = impl( creationState );
final NavigablePath relativePath = creationStateImpl.getCurrentRelativePath();
final Function<String, FetchBuilder> fetchBuilderResolver = creationStateImpl.getCurrentExplicitFetchMementoResolver();
final Map<NavigablePath, FetchBuilder> fetchBuilders = new LinkedHashMap<>( fetchable.getNumberOfFetchables() );
fetchable.visitFetchables(
subFetchable -> {
final NavigablePath subFetchPath = relativePath.append( subFetchable.getFetchableName() );
final FetchBuilder explicitFetchBuilder = fetchBuilderResolver
.apply( subFetchPath.getFullPath() );
if ( explicitFetchBuilder == null ) {
fetchBuilders.put(
subFetchPath,
Builders.implicitFetchBuilder( fetchPath, subFetchable, creationStateImpl )
);
}
else {
fetchBuilders.put( subFetchPath, explicitFetchBuilder );
}
},
null
);
this.fetchBuilders = fetchBuilders;
}
@Override
@ -70,30 +99,7 @@ public class ImplicitFetchBuilderEmbeddable implements ImplicitFetchBuilder {
}
);
fetchable.forEachSelection(
(columnIndex, selection) -> {
final TableReference tableReference = tableGroup.getTableReference( selection.getContainingTableExpression() );
final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( selection.getSelectionExpression() );
final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition );
final Expression expression = creationStateImpl.resolveSqlExpression(
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
processingState -> new SqlSelectionImpl(
valuesArrayPosition,
selection.getJdbcMapping()
)
);
creationStateImpl.resolveSqlSelection(
expression,
selection.getJdbcMapping().getJavaTypeDescriptor(),
creationStateImpl.getSessionFactory().getTypeConfiguration()
);
}
);
return fetchable.generateFetch(
final Fetch fetch = fetchable.generateFetch(
parent,
fetchPath,
FetchTiming.IMMEDIATE,
@ -102,6 +108,18 @@ public class ImplicitFetchBuilderEmbeddable implements ImplicitFetchBuilder {
null,
creationState
);
final FetchParent fetchParent = (FetchParent) fetch;
fetchBuilders.forEach(
(subFetchPath, fetchBuilder) -> fetchBuilder.buildFetch(
fetchParent,
subFetchPath,
jdbcResultsMetadata,
legacyFetchResolver,
creationState
)
);
return fetch;
}
@Override

View File

@ -152,8 +152,8 @@ public class EntityResultTests extends AbstractUsageTest {
"select id as id_alias,"
+ " type_code as type_code_alias,"
+ " root_name as root_name_alias,"
+ " subtype1_name as subtype1_name_alias,"
+ " subtype2_name as subtype2_name_alias"
+ " subtype1_name as sub_type1_name_alias,"
+ " subtype2_name as sub_type2_name_alias"
+ " from discriminated_entity";
final List<DiscriminatedRoot> results = session.createNativeQuery( qryString, "root-explicit" ).list();