discriminator work

- Handle discriminator as Fetch for entity ResultGraphNodes.  This allows us to make the distinction about whether to handle the discriminator as `Class` or as its "underlying" type when selecting it.  Fetches return the underlying type.  DomainResults return `Class`, or String for entity-named entity mappings
This commit is contained in:
Steve Ebersole 2021-08-20 13:03:16 -05:00
parent 83ac9d5d3d
commit c0de4c7854
21 changed files with 400 additions and 139 deletions

View File

@ -36,16 +36,15 @@ import org.hibernate.query.NavigablePath;
import org.hibernate.query.internal.FetchMementoBasicStandard; import org.hibernate.query.internal.FetchMementoBasicStandard;
import org.hibernate.query.internal.FetchMementoHbmStandard; import org.hibernate.query.internal.FetchMementoHbmStandard;
import org.hibernate.query.internal.FetchMementoHbmStandard.FetchParentMemento; import org.hibernate.query.internal.FetchMementoHbmStandard.FetchParentMemento;
import org.hibernate.query.internal.ModelPartResultMementoBasicImpl;
import org.hibernate.query.internal.NamedResultSetMappingMementoImpl; import org.hibernate.query.internal.NamedResultSetMappingMementoImpl;
import org.hibernate.query.internal.ResultMementoBasicStandard; import org.hibernate.query.internal.ResultMementoBasicStandard;
import org.hibernate.query.internal.ResultMementoCollectionStandard; import org.hibernate.query.internal.ResultMementoCollectionStandard;
import org.hibernate.query.internal.ResultMementoEntityStandard; import org.hibernate.query.internal.ResultMementoEntityStandard;
import org.hibernate.query.internal.ResultSetMappingResolutionContext; import org.hibernate.query.internal.ResultSetMappingResolutionContext;
import org.hibernate.query.named.FetchMemento; import org.hibernate.query.named.FetchMemento;
import org.hibernate.query.named.FetchMementoBasic;
import org.hibernate.query.named.NamedResultSetMappingMemento; import org.hibernate.query.named.NamedResultSetMappingMemento;
import org.hibernate.query.named.ResultMemento; import org.hibernate.query.named.ResultMemento;
import org.hibernate.query.named.ResultMementoBasic;
import org.hibernate.sql.results.graph.Fetchable; import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.FetchableContainer; import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
@ -375,7 +374,7 @@ public class HbmResultSetMappingDescriptor implements NamedResultSetMappingDescr
final NavigablePath entityPath = new NavigablePath( entityName ); final NavigablePath entityPath = new NavigablePath( entityName );
final ResultMementoBasic discriminatorMemento; final FetchMementoBasic discriminatorMemento;
if ( discriminatorColumnAlias == null ) { if ( discriminatorColumnAlias == null ) {
discriminatorMemento = null; discriminatorMemento = null;
} }
@ -387,7 +386,7 @@ public class HbmResultSetMappingDescriptor implements NamedResultSetMappingDescr
); );
} }
discriminatorMemento = new ModelPartResultMementoBasicImpl( discriminatorMemento = new FetchMementoBasicStandard(
entityPath.append( EntityDiscriminatorMapping.ROLE_NAME ), entityPath.append( EntityDiscriminatorMapping.ROLE_NAME ),
entityDescriptor.getDiscriminatorMapping(), entityDescriptor.getDiscriminatorMapping(),
discriminatorColumnAlias discriminatorColumnAlias

View File

@ -41,13 +41,10 @@ import org.hibernate.query.internal.ResultMementoEntityJpa;
import org.hibernate.query.internal.ResultMementoInstantiationStandard; import org.hibernate.query.internal.ResultMementoInstantiationStandard;
import org.hibernate.query.internal.ResultSetMappingResolutionContext; import org.hibernate.query.internal.ResultSetMappingResolutionContext;
import org.hibernate.query.named.FetchMemento; import org.hibernate.query.named.FetchMemento;
import org.hibernate.query.named.ModelPartResultMementoBasic; import org.hibernate.query.named.FetchMementoBasic;
import org.hibernate.query.named.NamedResultSetMappingMemento; import org.hibernate.query.named.NamedResultSetMappingMemento;
import org.hibernate.query.named.ResultMemento; import org.hibernate.query.named.ResultMemento;
import org.hibernate.query.named.ResultMementoBasic;
import org.hibernate.query.named.ResultMementoInstantiation.ArgumentMemento; import org.hibernate.query.named.ResultMementoInstantiation.ArgumentMemento;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/** /**
@ -275,7 +272,7 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
final RuntimeMetamodels runtimeMetamodels = resolutionContext.getSessionFactory().getRuntimeMetamodels(); final RuntimeMetamodels runtimeMetamodels = resolutionContext.getSessionFactory().getRuntimeMetamodels();
final EntityMappingType entityDescriptor = runtimeMetamodels.getEntityMappingType( entityName ); final EntityMappingType entityDescriptor = runtimeMetamodels.getEntityMappingType( entityName );
final ResultMementoBasic discriminatorMemento = resolveDiscriminatorMemento( final FetchMementoBasic discriminatorMemento = resolveDiscriminatorMemento(
entityDescriptor, entityDescriptor,
discriminatorColumn, discriminatorColumn,
navigablePath navigablePath
@ -297,7 +294,7 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
); );
} }
private static ModelPartResultMementoBasic resolveDiscriminatorMemento( private static FetchMementoBasic resolveDiscriminatorMemento(
EntityMappingType entityMapping, EntityMappingType entityMapping,
String discriminatorColumn, String discriminatorColumn,
NavigablePath entityPath) { NavigablePath entityPath) {
@ -310,7 +307,7 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
return null; return null;
} }
return new ModelPartResultMementoBasicImpl( return new FetchMementoBasicStandard(
entityPath.append( EntityDiscriminatorMapping.ROLE_NAME ), entityPath.append( EntityDiscriminatorMapping.ROLE_NAME ),
discriminatorMapping, discriminatorMapping,
discriminatorColumn discriminatorColumn

View File

@ -6,15 +6,21 @@
*/ */
package org.hibernate.metamodel.mapping; package org.hibernate.metamodel.mapping;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchOptions;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.basic.BasicFetch;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface EntityDiscriminatorMapping extends VirtualModelPart, BasicValuedModelPart { public interface EntityDiscriminatorMapping extends VirtualModelPart, BasicValuedModelPart, FetchOptions {
String ROLE_NAME = "{discriminator}"; String ROLE_NAME = "{discriminator}";
String LEGACY_HQL_ROLE_NAME = "class"; String LEGACY_HQL_ROLE_NAME = "class";
@ -27,6 +33,47 @@ public interface EntityDiscriminatorMapping extends VirtualModelPart, BasicValue
return ROLE_NAME; return ROLE_NAME;
} }
@Override
default String getFetchableName() {
return getPartName();
}
String getConcreteEntityNameForDiscriminatorValue(Object value);
@Override
BasicFetch generateFetch(
FetchParent fetchParent,
NavigablePath fetchablePath,
FetchTiming fetchTiming,
boolean selected,
String resultVariable,
DomainResultCreationState creationState);
@Override
default FetchOptions getMappedFetchOptions() {
return this;
}
@Override
default FetchStyle getStyle() {
return FetchStyle.JOIN;
}
@Override
default FetchTiming getTiming() {
return FetchTiming.IMMEDIATE;
}
@Override
default Fetch resolveCircularFetch(
NavigablePath fetchablePath,
FetchParent fetchParent,
FetchTiming fetchTiming,
DomainResultCreationState creationState) {
// can never be circular
return null;
}
<T> DomainResult<T> createUnderlyingDomainResult( <T> DomainResult<T> createUnderlyingDomainResult(
NavigablePath navigablePath, NavigablePath navigablePath,
TableGroup tableGroup, TableGroup tableGroup,

View File

@ -6,20 +6,18 @@
*/ */
package org.hibernate.metamodel.mapping.internal; package org.hibernate.metamodel.mapping.internal;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming; import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.persister.entity.DiscriminatorType; import org.hibernate.persister.entity.DiscriminatorType;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Loadable;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchOptions;
import org.hibernate.sql.results.graph.FetchParent; import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.basic.BasicFetch; import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.sql.results.graph.basic.BasicResult; import org.hibernate.sql.results.graph.basic.BasicResult;
@ -28,7 +26,7 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/** /**
* @author Andrea Boriero * @author Andrea Boriero
*/ */
public abstract class AbstractEntityDiscriminatorMapping implements EntityDiscriminatorMapping, FetchOptions { public abstract class AbstractEntityDiscriminatorMapping implements EntityDiscriminatorMapping {
private final EntityPersister entityDescriptor; private final EntityPersister entityDescriptor;
private final String tableExpression; private final String tableExpression;
private final String mappedColumnExpression; private final String mappedColumnExpression;
@ -69,23 +67,8 @@ public abstract class AbstractEntityDiscriminatorMapping implements EntityDiscri
} }
@Override @Override
public String getFetchableName() { public String getConcreteEntityNameForDiscriminatorValue(Object value) {
return ROLE_NAME; return ( (Loadable) getEntityDescriptor() ).getSubclassForDiscriminatorValue( value );
}
@Override
public FetchOptions getMappedFetchOptions() {
return this;
}
@Override
public FetchStyle getStyle() {
return FetchStyle.JOIN;
}
@Override
public FetchTiming getTiming() {
return FetchTiming.IMMEDIATE;
} }
@Override @Override
@ -131,7 +114,7 @@ public abstract class AbstractEntityDiscriminatorMapping implements EntityDiscri
} }
@Override @Override
public Fetch generateFetch( public BasicFetch generateFetch(
FetchParent fetchParent, FetchParent fetchParent,
NavigablePath fetchablePath, NavigablePath fetchablePath,
FetchTiming fetchTiming, FetchTiming fetchTiming,

View File

@ -12,34 +12,33 @@ import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.results.BasicValuedFetchBuilder;
import org.hibernate.query.results.ResultBuilder; import org.hibernate.query.results.ResultBuilder;
import org.hibernate.query.results.ResultBuilderBasicValued;
import org.hibernate.query.results.complete.EntityResultImpl; import org.hibernate.query.results.complete.EntityResultImpl;
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy; import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
import org.hibernate.query.results.implicit.ImplicitModelPartResultBuilderBasic; import org.hibernate.query.results.implicit.ImplicitFetchBuilderBasic;
import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.sql.results.graph.entity.EntityResult; import org.hibernate.sql.results.graph.entity.EntityResult;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
/** /**
* @author Christian Beikov * @author Christian Beikov
*/ */
public class EntityDomainResultBuilder<T> implements ResultBuilder { public class EntityDomainResultBuilder implements ResultBuilder {
private final NavigablePath navigablePath; private final NavigablePath navigablePath;
private final EntityMappingType entityDescriptor; private final EntityMappingType entityDescriptor;
private final ResultBuilderBasicValued discriminatorResultBuilder; private final BasicValuedFetchBuilder discriminatorFetchBuilder;
public EntityDomainResultBuilder(EntityMappingType entityDescriptor) { public EntityDomainResultBuilder(EntityMappingType entityDescriptor) {
this.entityDescriptor = entityDescriptor; this.entityDescriptor = entityDescriptor;
this.navigablePath = new NavigablePath( entityDescriptor.getEntityName() ); this.navigablePath = new NavigablePath( entityDescriptor.getEntityName() );
final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping(); final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping();
if ( discriminatorMapping == null ) { if ( discriminatorMapping == null ) {
this.discriminatorResultBuilder = null; this.discriminatorFetchBuilder = null;
} }
else { else {
this.discriminatorResultBuilder = new ImplicitModelPartResultBuilderBasic( this.discriminatorFetchBuilder = new ImplicitFetchBuilderBasic(
navigablePath, navigablePath,
discriminatorMapping discriminatorMapping
); );
@ -52,25 +51,24 @@ public class EntityDomainResultBuilder<T> implements ResultBuilder {
int resultPosition, int resultPosition,
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver, BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
DomainResultCreationState domainResultCreationState) { DomainResultCreationState domainResultCreationState) {
final BasicResult<?> discriminatorResult;
if ( discriminatorResultBuilder == null ) {
discriminatorResult = null;
}
else {
discriminatorResult = discriminatorResultBuilder.buildResult(
jdbcResultsMetadata,
resultPosition,
legacyFetchResolver,
domainResultCreationState
);
}
return new EntityResultImpl( return new EntityResultImpl(
navigablePath, navigablePath,
entityDescriptor, entityDescriptor,
null, null,
LockMode.NONE, LockMode.NONE,
discriminatorResult, entityResult -> {
if ( discriminatorFetchBuilder == null ) {
return null;
}
return discriminatorFetchBuilder.buildFetch(
entityResult,
navigablePath.append( EntityDiscriminatorMapping.ROLE_NAME ),
jdbcResultsMetadata,
legacyFetchResolver,
domainResultCreationState
);
},
domainResultCreationState domainResultCreationState
); );
} }

View File

@ -15,13 +15,13 @@ import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.named.FetchMemento; import org.hibernate.query.named.FetchMemento;
import org.hibernate.query.named.ResultMementoBasic; import org.hibernate.query.named.FetchMementoBasic;
import org.hibernate.query.named.ResultMementoEntity; import org.hibernate.query.named.ResultMementoEntity;
import org.hibernate.query.results.BasicValuedFetchBuilder;
import org.hibernate.query.results.FetchBuilder; import org.hibernate.query.results.FetchBuilder;
import org.hibernate.query.results.ResultBuilderBasicValued;
import org.hibernate.query.results.ResultBuilderEntityValued; import org.hibernate.query.results.ResultBuilderEntityValued;
import org.hibernate.query.results.complete.CompleteResultBuilderEntityJpa; import org.hibernate.query.results.complete.CompleteResultBuilderEntityJpa;
import org.hibernate.query.results.implicit.ImplicitModelPartResultBuilderBasic; import org.hibernate.query.results.implicit.ImplicitFetchBuilderBasic;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -30,14 +30,13 @@ public class ResultMementoEntityJpa implements ResultMementoEntity, FetchMemento
private final NavigablePath navigablePath; private final NavigablePath navigablePath;
private final EntityMappingType entityDescriptor; private final EntityMappingType entityDescriptor;
private final LockMode lockMode; private final LockMode lockMode;
// private final ResultMemento identifierMemento; private final FetchMementoBasic discriminatorMemento;
private final ResultMementoBasic discriminatorMemento;
private final Map<String, FetchMemento> explicitFetchMementoMap; private final Map<String, FetchMemento> explicitFetchMementoMap;
public ResultMementoEntityJpa( public ResultMementoEntityJpa(
EntityMappingType entityDescriptor, EntityMappingType entityDescriptor,
LockMode lockMode, LockMode lockMode,
ResultMementoBasic discriminatorMemento, FetchMementoBasic discriminatorMemento,
Map<String, FetchMemento> explicitFetchMementoMap) { Map<String, FetchMemento> explicitFetchMementoMap) {
this.navigablePath = new NavigablePath( entityDescriptor.getEntityName() ); this.navigablePath = new NavigablePath( entityDescriptor.getEntityName() );
this.entityDescriptor = entityDescriptor; this.entityDescriptor = entityDescriptor;
@ -56,17 +55,17 @@ public class ResultMementoEntityJpa implements ResultMementoEntity, FetchMemento
Consumer<String> querySpaceConsumer, Consumer<String> querySpaceConsumer,
ResultSetMappingResolutionContext context) { ResultSetMappingResolutionContext context) {
final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping(); final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping();
final ResultBuilderBasicValued discriminatorResultBuilder; final BasicValuedFetchBuilder discriminatorFetchBuilder;
if ( discriminatorMapping == null ) { if ( discriminatorMapping == null ) {
assert discriminatorMemento == null; assert discriminatorMemento == null;
discriminatorResultBuilder = null; discriminatorFetchBuilder = null;
} }
else { else {
if ( discriminatorMemento != null ) { if ( discriminatorMemento != null ) {
discriminatorResultBuilder = discriminatorMemento.resolve( querySpaceConsumer, context ); discriminatorFetchBuilder = (BasicValuedFetchBuilder) discriminatorMemento.resolve( this, querySpaceConsumer, context );
} }
else { else {
discriminatorResultBuilder = new ImplicitModelPartResultBuilderBasic( navigablePath, discriminatorMapping ); discriminatorFetchBuilder = new ImplicitFetchBuilderBasic( navigablePath, discriminatorMapping );
} }
} }
@ -83,7 +82,7 @@ public class ResultMementoEntityJpa implements ResultMementoEntity, FetchMemento
navigablePath, navigablePath,
entityDescriptor, entityDescriptor,
lockMode, lockMode,
discriminatorResultBuilder, discriminatorFetchBuilder,
explicitFetchBuilderMap explicitFetchBuilderMap
); );
} }

View File

@ -15,10 +15,10 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.QueryLogging; import org.hibernate.query.QueryLogging;
import org.hibernate.query.named.FetchMemento; import org.hibernate.query.named.FetchMemento;
import org.hibernate.query.named.ResultMementoBasic; import org.hibernate.query.named.FetchMementoBasic;
import org.hibernate.query.named.ResultMementoEntity; import org.hibernate.query.named.ResultMementoEntity;
import org.hibernate.query.results.BasicValuedFetchBuilder;
import org.hibernate.query.results.FetchBuilder; import org.hibernate.query.results.FetchBuilder;
import org.hibernate.query.results.ResultBuilderBasicValued;
import org.hibernate.query.results.ResultBuilderEntityValued; import org.hibernate.query.results.ResultBuilderEntityValued;
import org.hibernate.query.results.complete.CompleteResultBuilderEntityStandard; import org.hibernate.query.results.complete.CompleteResultBuilderEntityStandard;
@ -30,14 +30,14 @@ public class ResultMementoEntityStandard implements ResultMementoEntity, FetchMe
private final NavigablePath navigablePath; private final NavigablePath navigablePath;
private final EntityMappingType entityDescriptor; private final EntityMappingType entityDescriptor;
private final LockMode lockMode; private final LockMode lockMode;
private final ResultMementoBasic discriminatorMemento; private final FetchMementoBasic discriminatorMemento;
private final Map<String, FetchMemento> fetchMementoMap; private final Map<String, FetchMemento> fetchMementoMap;
public ResultMementoEntityStandard( public ResultMementoEntityStandard(
String tableAlias, String tableAlias,
EntityMappingType entityDescriptor, EntityMappingType entityDescriptor,
LockMode lockMode, LockMode lockMode,
ResultMementoBasic discriminatorMemento, FetchMementoBasic discriminatorMemento,
Map<String, FetchMemento> fetchMementoMap) { Map<String, FetchMemento> fetchMementoMap) {
this.tableAlias = tableAlias; this.tableAlias = tableAlias;
this.navigablePath = new NavigablePath( entityDescriptor.getEntityName() ); this.navigablePath = new NavigablePath( entityDescriptor.getEntityName() );
@ -61,8 +61,9 @@ public class ResultMementoEntityStandard implements ResultMementoEntity, FetchMe
public ResultBuilderEntityValued resolve( public ResultBuilderEntityValued resolve(
Consumer<String> querySpaceConsumer, Consumer<String> querySpaceConsumer,
ResultSetMappingResolutionContext context) { ResultSetMappingResolutionContext context) {
final ResultBuilderBasicValued discriminatorResultBuilder = discriminatorMemento != null
? discriminatorMemento.resolve( querySpaceConsumer, context ) final BasicValuedFetchBuilder discriminatorResultBuilder = discriminatorMemento != null
? (BasicValuedFetchBuilder) discriminatorMemento.resolve( this, querySpaceConsumer, context )
: null; : null;
final HashMap<String, FetchBuilder> fetchBuilderMap = new HashMap<>(); final HashMap<String, FetchBuilder> fetchBuilderMap = new HashMap<>();

View File

@ -0,0 +1,29 @@
/*
* 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.results;
import java.util.function.BiFunction;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
/**
* @author Steve Ebersole
*/
public interface BasicValuedFetchBuilder extends FetchBuilder {
@Override
BasicFetch<?> buildFetch(
FetchParent parent,
NavigablePath fetchPath,
JdbcValuesMetadata jdbcResultsMetadata,
BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver,
DomainResultCreationState domainResultCreationState);
}

View File

@ -11,6 +11,7 @@ import java.util.function.BiFunction;
import org.hibernate.engine.FetchTiming; import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.mapping.BasicValuedModelPart; import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.results.BasicValuedFetchBuilder;
import org.hibernate.query.results.DomainResultCreationStateImpl; import org.hibernate.query.results.DomainResultCreationStateImpl;
import org.hibernate.query.results.MissingSqlSelectionException; import org.hibernate.query.results.MissingSqlSelectionException;
import org.hibernate.query.results.PositionalSelectionsNotAllowedException; import org.hibernate.query.results.PositionalSelectionsNotAllowedException;
@ -19,8 +20,8 @@ import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.results.graph.DomainResultCreationState; 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.FetchParent;
import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
import static org.hibernate.query.results.ResultsHelper.impl; import static org.hibernate.query.results.ResultsHelper.impl;
@ -30,7 +31,7 @@ import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnRefere
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class CompleteFetchBuilderBasicPart implements CompleteFetchBuilder, ModelPartReferenceBasic { public class CompleteFetchBuilderBasicPart implements CompleteFetchBuilder, BasicValuedFetchBuilder, ModelPartReferenceBasic {
private final NavigablePath navigablePath; private final NavigablePath navigablePath;
private final BasicValuedModelPart referencedModelPart; private final BasicValuedModelPart referencedModelPart;
private final String selectionAlias; private final String selectionAlias;
@ -55,7 +56,7 @@ public class CompleteFetchBuilderBasicPart implements CompleteFetchBuilder, Mode
} }
@Override @Override
public Fetch buildFetch( public BasicFetch<?> buildFetch(
FetchParent parent, FetchParent parent,
NavigablePath fetchPath, NavigablePath fetchPath,
JdbcValuesMetadata jdbcResultsMetadata, JdbcValuesMetadata jdbcResultsMetadata,
@ -103,7 +104,7 @@ public class CompleteFetchBuilderBasicPart implements CompleteFetchBuilder, Mode
processingState -> new SqlSelectionImpl( valuesArrayPosition, referencedModelPart ) processingState -> new SqlSelectionImpl( valuesArrayPosition, referencedModelPart )
); );
return parent.generateFetchableFetch( return (BasicFetch<?>) parent.generateFetchableFetch(
referencedModelPart, referencedModelPart,
fetchPath, fetchPath,
FetchTiming.IMMEDIATE, FetchTiming.IMMEDIATE,

View File

@ -14,13 +14,12 @@ import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.results.BasicValuedFetchBuilder;
import org.hibernate.query.results.DomainResultCreationStateImpl; import org.hibernate.query.results.DomainResultCreationStateImpl;
import org.hibernate.query.results.FetchBuilder; import org.hibernate.query.results.FetchBuilder;
import org.hibernate.query.results.ResultBuilderBasicValued;
import org.hibernate.query.results.ResultsHelper; import org.hibernate.query.results.ResultsHelper;
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy; import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.sql.results.graph.entity.EntityResult; import org.hibernate.sql.results.graph.entity.EntityResult;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
@ -38,20 +37,29 @@ public class CompleteResultBuilderEntityJpa implements CompleteResultBuilderEnti
private final NavigablePath navigablePath; private final NavigablePath navigablePath;
private final EntityMappingType entityDescriptor; private final EntityMappingType entityDescriptor;
private final LockMode lockMode; private final LockMode lockMode;
private final ResultBuilderBasicValued discriminatorResultBuilder; private final BasicValuedFetchBuilder discriminatorFetchBuilder;
private final HashMap<String, FetchBuilder> explicitFetchBuilderMap; private final HashMap<String, FetchBuilder> explicitFetchBuilderMap;
public CompleteResultBuilderEntityJpa( public CompleteResultBuilderEntityJpa(
NavigablePath navigablePath, NavigablePath navigablePath,
EntityMappingType entityDescriptor, EntityMappingType entityDescriptor,
LockMode lockMode, LockMode lockMode,
ResultBuilderBasicValued discriminatorResultBuilder, BasicValuedFetchBuilder discriminatorFetchBuilder,
HashMap<String, FetchBuilder> explicitFetchBuilderMap) { HashMap<String, FetchBuilder> explicitFetchBuilderMap) {
this.navigablePath = navigablePath; this.navigablePath = navigablePath;
this.entityDescriptor = entityDescriptor; this.entityDescriptor = entityDescriptor;
this.lockMode = lockMode; this.lockMode = lockMode;
this.discriminatorResultBuilder = discriminatorResultBuilder; this.discriminatorFetchBuilder = discriminatorFetchBuilder;
this.explicitFetchBuilderMap = explicitFetchBuilderMap; this.explicitFetchBuilderMap = explicitFetchBuilderMap;
if ( entityDescriptor.getDiscriminatorMapping() == null ) {
// not discriminated
assert discriminatorFetchBuilder == null;
}
else {
// discriminated
assert discriminatorFetchBuilder != null;
}
} }
@Override @Override
@ -90,28 +98,24 @@ public class CompleteResultBuilderEntityJpa implements CompleteResultBuilderEnti
) )
); );
final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping();
final BasicResult<?> discriminatorResult;
if ( discriminatorMapping == null ) {
assert discriminatorResultBuilder == null;
discriminatorResult = null;
}
else {
assert discriminatorResultBuilder != null;
discriminatorResult = discriminatorResultBuilder.buildResult(
jdbcResultsMetadata,
resultPosition,
legacyFetchResolver,
domainResultCreationState
);
}
return new EntityResultImpl( return new EntityResultImpl(
navigablePath, navigablePath,
entityDescriptor, entityDescriptor,
null, null,
lockMode, lockMode,
discriminatorResult, (entityResult) -> {
if ( discriminatorFetchBuilder == null ) {
return null;
}
return discriminatorFetchBuilder.buildFetch(
entityResult,
navigablePath.append( EntityDiscriminatorMapping.ROLE_NAME ),
jdbcResultsMetadata,
legacyFetchResolver,
domainResultCreationState
);
},
domainResultCreationState domainResultCreationState
); );
} }

View File

@ -11,16 +11,16 @@ import java.util.function.BiConsumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.query.NativeQuery; import org.hibernate.query.NativeQuery;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.results.BasicValuedFetchBuilder;
import org.hibernate.query.results.DomainResultCreationStateImpl; import org.hibernate.query.results.DomainResultCreationStateImpl;
import org.hibernate.query.results.FetchBuilder; import org.hibernate.query.results.FetchBuilder;
import org.hibernate.query.results.ResultBuilderBasicValued;
import org.hibernate.query.results.ResultsHelper; import org.hibernate.query.results.ResultsHelper;
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy; import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.sql.results.graph.entity.EntityResult; import org.hibernate.sql.results.graph.entity.EntityResult;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
@ -32,7 +32,7 @@ public class CompleteResultBuilderEntityStandard implements CompleteResultBuilde
private final NavigablePath navigablePath; private final NavigablePath navigablePath;
private final EntityMappingType entityDescriptor; private final EntityMappingType entityDescriptor;
private final LockMode lockMode; private final LockMode lockMode;
private final ResultBuilderBasicValued discriminatorResultBuilder; private final BasicValuedFetchBuilder discriminatorFetchBuilder;
private final HashMap<String, FetchBuilder> explicitFetchBuilderMap; private final HashMap<String, FetchBuilder> explicitFetchBuilderMap;
public CompleteResultBuilderEntityStandard( public CompleteResultBuilderEntityStandard(
@ -40,13 +40,13 @@ public class CompleteResultBuilderEntityStandard implements CompleteResultBuilde
NavigablePath navigablePath, NavigablePath navigablePath,
EntityMappingType entityDescriptor, EntityMappingType entityDescriptor,
LockMode lockMode, LockMode lockMode,
ResultBuilderBasicValued discriminatorResultBuilder, BasicValuedFetchBuilder discriminatorFetchBuilder,
HashMap<String, FetchBuilder> explicitFetchBuilderMap) { HashMap<String, FetchBuilder> explicitFetchBuilderMap) {
this.tableAlias = tableAlias; this.tableAlias = tableAlias;
this.navigablePath = navigablePath; this.navigablePath = navigablePath;
this.entityDescriptor = entityDescriptor; this.entityDescriptor = entityDescriptor;
this.lockMode = lockMode; this.lockMode = lockMode;
this.discriminatorResultBuilder = discriminatorResultBuilder; this.discriminatorFetchBuilder = discriminatorFetchBuilder;
this.explicitFetchBuilderMap = explicitFetchBuilderMap; this.explicitFetchBuilderMap = explicitFetchBuilderMap;
} }
@ -126,25 +126,24 @@ public class CompleteResultBuilderEntityStandard implements CompleteResultBuilde
) )
); );
final BasicResult<?> discriminatorResult;
if ( discriminatorResultBuilder != null ) {
discriminatorResult = discriminatorResultBuilder.buildResult(
jdbcResultsMetadata,
resultPosition,
legacyFetchResolver,
domainResultCreationState
);
}
else {
discriminatorResult = null;
}
return new EntityResultImpl( return new EntityResultImpl(
navigablePath, navigablePath,
entityDescriptor, entityDescriptor,
null, null,
lockMode, lockMode,
discriminatorResult, (entityResult) -> {
if ( discriminatorFetchBuilder == null ) {
return null;
}
return discriminatorFetchBuilder.buildFetch(
entityResult,
navigablePath.append( EntityDiscriminatorMapping.ROLE_NAME ),
jdbcResultsMetadata,
legacyFetchResolver,
domainResultCreationState
);
},
domainResultCreationState domainResultCreationState
); );
} }

View File

@ -7,6 +7,7 @@
package org.hibernate.query.results.complete; package org.hibernate.query.results.complete;
import java.util.List; import java.util.List;
import java.util.function.Function;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.internal.util.MutableObject; import org.hibernate.internal.util.MutableObject;
@ -22,7 +23,7 @@ import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.Fetchable; import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.basic.BasicResult; import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.sql.results.graph.entity.EntityInitializer; import org.hibernate.sql.results.graph.entity.EntityInitializer;
import org.hibernate.sql.results.graph.entity.EntityResult; import org.hibernate.sql.results.graph.entity.EntityResult;
import org.hibernate.sql.results.graph.entity.internal.EntityAssembler; import org.hibernate.sql.results.graph.entity.internal.EntityAssembler;
@ -36,25 +37,43 @@ public class EntityResultImpl implements EntityResult {
private final EntityValuedModelPart entityValuedModelPart; private final EntityValuedModelPart entityValuedModelPart;
private final DomainResult identifierResult; private final DomainResult identifierResult;
private final BasicResult discriminatorResult; private final Fetch discriminatorFetch;
private final List<Fetch> fetches; private final List<Fetch> fetches;
private final String resultAlias; private final String resultAlias;
private final LockMode lockMode; private final LockMode lockMode;
public EntityResultImpl(
NavigablePath navigablePath,
EntityValuedModelPart entityValuedModelPart,
String resultAlias,
LockMode lockMode,
BasicFetch<?> discriminatorFetch,
DomainResultCreationState creationState) {
this(
navigablePath,
entityValuedModelPart,
resultAlias,
lockMode,
entityResult -> discriminatorFetch,
creationState
);
}
@SuppressWarnings( { "PointlessNullCheck" } ) @SuppressWarnings( { "PointlessNullCheck" } )
public EntityResultImpl( public EntityResultImpl(
NavigablePath navigablePath, NavigablePath navigablePath,
EntityValuedModelPart entityValuedModelPart, EntityValuedModelPart entityValuedModelPart,
String resultAlias, String resultAlias,
LockMode lockMode, LockMode lockMode,
BasicResult<?> discriminatorResult, Function<EntityResultImpl, BasicFetch> discriminatorFetchBuilder,
DomainResultCreationState creationState) { DomainResultCreationState creationState) {
this.navigablePath = navigablePath; this.navigablePath = navigablePath;
this.entityValuedModelPart = entityValuedModelPart; this.entityValuedModelPart = entityValuedModelPart;
this.resultAlias = resultAlias; this.resultAlias = resultAlias;
this.lockMode = lockMode; this.lockMode = lockMode;
this.discriminatorResult = discriminatorResult;
this.discriminatorFetch = discriminatorFetchBuilder.apply( this );
this.fetches = creationState.visitFetches( this ); this.fetches = creationState.visitFetches( this );
@ -141,7 +160,7 @@ public class EntityResultImpl implements EntityResult {
getNavigablePath(), getNavigablePath(),
lockMode, lockMode,
identifierResult, identifierResult,
discriminatorResult, discriminatorFetch,
null, null,
null, null,
creationState creationState

View File

@ -13,6 +13,7 @@ import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.ConvertibleModelPart; import org.hibernate.metamodel.mapping.ConvertibleModelPart;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.results.BasicValuedFetchBuilder;
import org.hibernate.query.results.DomainResultCreationStateImpl; import org.hibernate.query.results.DomainResultCreationStateImpl;
import org.hibernate.query.results.ResultsHelper; import org.hibernate.query.results.ResultsHelper;
import org.hibernate.query.results.SqlSelectionImpl; import org.hibernate.query.results.SqlSelectionImpl;
@ -31,7 +32,7 @@ import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnRefere
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder { public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder, BasicValuedFetchBuilder {
private final NavigablePath fetchPath; private final NavigablePath fetchPath;
private final BasicValuedModelPart fetchable; private final BasicValuedModelPart fetchable;

View File

@ -35,7 +35,6 @@ import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.EntityValuedModelPart; import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Loadable;
import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer; import org.hibernate.proxy.LazyInitializer;
import org.hibernate.proxy.map.MapProxy; import org.hibernate.proxy.map.MapProxy;
@ -99,7 +98,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
NavigablePath navigablePath, NavigablePath navigablePath,
LockMode lockMode, LockMode lockMode,
DomainResult<?> identifierResult, DomainResult<?> identifierResult,
DomainResult<?> discriminatorResult, Fetch discriminatorFetch,
DomainResult<?> versionResult, DomainResult<?> versionResult,
DomainResult<Object> rowIdResult, DomainResult<Object> rowIdResult,
AssemblerCreationState creationState) { AssemblerCreationState creationState) {
@ -170,8 +169,8 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
this.identifierAssembler = null; this.identifierAssembler = null;
} }
if ( discriminatorResult != null ) { if ( discriminatorFetch != null ) {
discriminatorAssembler = discriminatorResult.createResultAssembler( creationState ); discriminatorAssembler = discriminatorFetch.createAssembler( this, creationState );
} }
else { else {
discriminatorAssembler = null; discriminatorAssembler = null;
@ -337,7 +336,8 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
rowProcessingState.getJdbcValuesSourceProcessingState().getProcessingOptions() rowProcessingState.getJdbcValuesSourceProcessingState().getProcessingOptions()
); );
final String concreteEntityName = ( (Loadable) entityDescriptor.getRootEntityDescriptor() ).getSubclassForDiscriminatorValue( discriminatorValue ); final String concreteEntityName = entityDescriptor.getDiscriminatorMapping().getConcreteEntityNameForDiscriminatorValue( discriminatorValue );
if ( concreteEntityName == null ) { if ( concreteEntityName == null ) {
return entityDescriptor; return entityDescriptor;
} }

View File

@ -6,7 +6,7 @@
*/ */
package org.hibernate.sql.results.graph.entity; package org.hibernate.sql.results.graph.entity;
import org.hibernate.LockMode; import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityMappingType;
@ -24,6 +24,7 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.graph.AbstractFetchParent; import org.hibernate.sql.results.graph.AbstractFetchParent;
import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import static org.hibernate.query.results.ResultsHelper.attributeName; import static org.hibernate.query.results.ResultsHelper.attributeName;
@ -36,7 +37,7 @@ import static org.hibernate.query.results.ResultsHelper.attributeName;
public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent implements EntityResultGraphNode { public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent implements EntityResultGraphNode {
private final EntityValuedModelPart referencedModelPart; private final EntityValuedModelPart referencedModelPart;
private final DomainResult identifierResult; private final DomainResult identifierResult;
private final DomainResult discriminatorResult; private final Fetch discriminatorFetch;
private final DomainResult versionResult; private final DomainResult versionResult;
private final DomainResult<Object> rowIdResult; private final DomainResult<Object> rowIdResult;
@ -104,15 +105,17 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent
final EntityDiscriminatorMapping discriminatorMapping = getDiscriminatorMapping( entityDescriptor, entityTableGroup ); final EntityDiscriminatorMapping discriminatorMapping = getDiscriminatorMapping( entityDescriptor, entityTableGroup );
// No need to fetch the discriminator if this type does not have subclasses // No need to fetch the discriminator if this type does not have subclasses
if ( discriminatorMapping != null && entityDescriptor.getEntityPersister().getEntityMetamodel().hasSubclasses() ) { if ( discriminatorMapping != null && entityDescriptor.getEntityPersister().getEntityMetamodel().hasSubclasses() ) {
discriminatorResult = discriminatorMapping.createUnderlyingDomainResult( discriminatorFetch = discriminatorMapping.generateFetch(
this,
navigablePath.append( EntityDiscriminatorMapping.ROLE_NAME ), navigablePath.append( EntityDiscriminatorMapping.ROLE_NAME ),
entityTableGroup, FetchTiming.IMMEDIATE,
true,
null, null,
creationState creationState
); );
} }
else { else {
discriminatorResult = null; discriminatorFetch = null;
} }
final EntityVersionMapping versionDescriptor = entityDescriptor.getVersionMapping(); final EntityVersionMapping versionDescriptor = entityDescriptor.getVersionMapping();
@ -205,8 +208,8 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent
return identifierResult; return identifierResult;
} }
public DomainResult getDiscriminatorResult() { public Fetch getDiscriminatorFetch() {
return discriminatorResult; return discriminatorFetch;
} }
public DomainResult getVersionResult() { public DomainResult getVersionResult() {

View File

@ -57,7 +57,7 @@ public class EntityFetchJoinedImpl extends AbstractNonLazyEntityFetch {
getNavigablePath(), getNavigablePath(),
creationState.determineEffectiveLockMode( sourceAlias ), creationState.determineEffectiveLockMode( sourceAlias ),
entityResult.getIdentifierResult(), entityResult.getIdentifierResult(),
entityResult.getDiscriminatorResult(), entityResult.getDiscriminatorFetch(),
entityResult.getVersionResult(), entityResult.getVersionResult(),
creationState creationState
) )

View File

@ -19,6 +19,8 @@ import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.sql.results.graph.AssemblerCreationState; import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.sql.results.graph.entity.AbstractEntityInitializer; import org.hibernate.sql.results.graph.entity.AbstractEntityInitializer;
import org.hibernate.sql.results.graph.entity.EntityResultGraphNode; import org.hibernate.sql.results.graph.entity.EntityResultGraphNode;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState; import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
@ -38,7 +40,7 @@ public class EntityJoinedFetchInitializer extends AbstractEntityInitializer {
NavigablePath navigablePath, NavigablePath navigablePath,
LockMode lockMode, LockMode lockMode,
DomainResult<?> identifierResult, DomainResult<?> identifierResult,
DomainResult<?> discriminatorResult, Fetch discriminatorResult,
DomainResult<?> versionResult, DomainResult<?> versionResult,
AssemblerCreationState creationState) { AssemblerCreationState creationState) {
super( super(

View File

@ -103,7 +103,7 @@ public class EntityResultImpl extends AbstractEntityResultGraphNode implements E
getNavigablePath(), getNavigablePath(),
getLockMode( creationState ), getLockMode( creationState ),
getIdentifierResult(), getIdentifierResult(),
getDiscriminatorResult(), getDiscriminatorFetch(),
getVersionResult(), getVersionResult(),
getRowIdResult(), getRowIdResult(),
creationState creationState

View File

@ -10,6 +10,7 @@ import org.hibernate.LockMode;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.sql.results.graph.AssemblerCreationState; import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.entity.AbstractEntityInitializer; import org.hibernate.sql.results.graph.entity.AbstractEntityInitializer;
import org.hibernate.sql.results.graph.entity.EntityResultGraphNode; import org.hibernate.sql.results.graph.entity.EntityResultGraphNode;
@ -26,7 +27,7 @@ public class EntityResultInitializer extends AbstractEntityInitializer {
NavigablePath navigablePath, NavigablePath navigablePath,
LockMode lockMode, LockMode lockMode,
DomainResult identifierResult, DomainResult identifierResult,
DomainResult discriminatorResult, Fetch discriminatorResult,
DomainResult versionResult, DomainResult versionResult,
DomainResult<Object> rowIdResult, DomainResult<Object> rowIdResult,
AssemblerCreationState creationState) { AssemblerCreationState creationState) {

View File

@ -40,7 +40,7 @@ public class EntityResultJoinedSubclassImpl extends EntityResultImpl {
getNavigablePath(), getNavigablePath(),
getLockMode( creationState ), getLockMode( creationState ),
getIdentifierResult(), getIdentifierResult(),
getDiscriminatorResult(), getDiscriminatorFetch(),
getVersionResult(), getVersionResult(),
getRowIdResult(), getRowIdResult(),
creationState creationState

View File

@ -0,0 +1,178 @@
/*
* 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.orm.test.legacy;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.criteria.JpaCriteriaDelete;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Steve Ebersole
*/
@DomainModel(
annotatedClasses = {
AbcTransitionTests.EntityA.class,
AbcTransitionTests.EntityB.class,
AbcTransitionTests.EntityC1.class,
AbcTransitionTests.EntityC2.class,
AbcTransitionTests.EntityD.class
}
)
@SessionFactory
public class AbcTransitionTests {
/**
* @see ABCTest#testSubclassing
*/
@Test
public void testSubclassing(SessionFactoryScope scope) {
final EntityC1 created = scope.fromTransaction( (session) -> {
final EntityC1 entityC1 = new EntityC1( 1, "some text", "a b name", 1, "a c1 name", "a c1 address" );
session.save( entityC1 );
return entityC1;
} );
scope.inTransaction( (session) -> {
assertThat( session.createQuery( "from EntityC2 c where 1=1 or 1=1" ).list() ).hasSize( 0 );
final Object queried = session.createQuery( "from EntityA e where e.id = :id" )
.setParameter( "id", created.id )
.uniqueResult();
assertThat( queried ).isNotNull();
assertThat( queried ).isInstanceOf( EntityC1.class );
final EntityA loaded = session.get( EntityA.class, created.id );
assertThat( loaded ).isNotNull();
assertThat( loaded ).isInstanceOf( EntityC1.class );
} );
}
@AfterAll
public void dropTestData(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
final HibernateCriteriaBuilder criteriaBuilder = scope.getSessionFactory().getCriteriaBuilder();
session.createQuery( criteriaBuilder.createCriteriaDelete( EntityA.class ) ).executeUpdate();
session.createQuery( criteriaBuilder.createCriteriaDelete( EntityD.class ) ).executeUpdate();
} );
}
@Entity( name = "EntityA" )
@Table( name = "tbl_a" )
@Inheritance( strategy = InheritanceType.SINGLE_TABLE )
@DiscriminatorColumn( name = "clazz_discriminata" )
@DiscriminatorValue( "entity-a" )
public static class EntityA {
@Id
Integer id;
String text;
public EntityA() {
}
public EntityA(Integer id, String text) {
this.id = id;
this.text = text;
}
}
@Entity( name = "EntityB" )
@Table( name = "tbl_b" )
@DiscriminatorValue( "entity-b" )
public static class EntityB extends EntityA {
String bName;
int count;
public EntityB() {
}
public EntityB(int id, String text, String bName, int count) {
super( id, text );
this.count = count;
}
}
@Entity( name = "EntityC1" )
@Table( name = "tbl_c1" )
@DiscriminatorValue( "entity-c1" )
public static class EntityC1 extends EntityB {
String cName;
String cAddress;
public EntityC1() {
}
public EntityC1(int id, String text, String bName, int count, String name, String address) {
super( id, text, bName, count );
this.cName = name;
this.cAddress = address;
}
}
@Entity( name = "EntityC2" )
@Table( name = "tbl_c2" )
@DiscriminatorValue( "entity-c2" )
public static class EntityC2 extends EntityB {
String c2Name;
String c2Address;
public EntityC2() {
}
public EntityC2(Integer id, String text, String bName, int count, String name, String address) {
super( id, text, bName, count );
this.c2Name = name;
this.c2Address = address;
}
}
@Entity( name = "EntityD" )
@Table( name = "tbl_d" )
public static class EntityD {
@Id
Integer id;
String text;
@ManyToOne( fetch = FetchType.LAZY )
@JoinColumn( name = "rev_fk" )
EntityA reverse;
@ManyToOne( fetch = FetchType.LAZY )
@JoinColumn( name = "inv_fk" )
EntityA inverse;
public EntityD() {
}
public EntityD(Integer id, String text) {
this.id = id;
this.text = text;
}
}
}