HHH-15569 Replace list and map with array to improve state extraction for entity initializing
This commit is contained in:
parent
1d5f6b5c13
commit
99f9ccdd11
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.mapping;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -23,6 +24,7 @@ import org.hibernate.loader.ast.spi.NaturalIdLoader;
|
|||
import org.hibernate.mapping.IndexedConsumer;
|
||||
import org.hibernate.metamodel.UnsupportedMappingException;
|
||||
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
|
||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
|
||||
|
@ -167,6 +169,10 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel
|
|||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Inheritance
|
||||
|
||||
default int getSubclassId() {
|
||||
return getEntityPersister().getEntityMetamodel().getSubclassId();
|
||||
}
|
||||
|
||||
default boolean hasSubclasses() {
|
||||
return getEntityPersister().getEntityMetamodel().hasSubclasses();
|
||||
}
|
||||
|
@ -198,6 +204,16 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel
|
|||
return null;
|
||||
}
|
||||
|
||||
default Collection<EntityMappingType> getSubMappingTypes() {
|
||||
final MappingMetamodelImplementor mappingMetamodel = getEntityPersister().getFactory().getMappingMetamodel();
|
||||
final Set<String> subclassEntityNames = getSubclassEntityNames();
|
||||
final List<EntityMappingType> mappingTypes = new ArrayList<>( subclassEntityNames.size() );
|
||||
for ( String subclassEntityName : subclassEntityNames ) {
|
||||
mappingTypes.add( mappingMetamodel.getEntityDescriptor( subclassEntityName ) );
|
||||
}
|
||||
return mappingTypes;
|
||||
}
|
||||
|
||||
default boolean isTypeOrSuperType(EntityMappingType targetType) {
|
||||
return targetType == this;
|
||||
}
|
||||
|
@ -314,6 +330,7 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel
|
|||
|
||||
// Customer <- DomesticCustomer <- OtherCustomer
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
default Object[] extractConcreteTypeStateValues(
|
||||
Map<AttributeMapping, DomainResultAssembler> assemblerMapping,
|
||||
RowProcessingState rowProcessingState) {
|
||||
|
|
|
@ -1221,7 +1221,7 @@ public abstract class AbstractEntityPersister
|
|||
// of this class, not its subclasses, but since we
|
||||
// are reusing code used for sequential selects, we
|
||||
// use the subclass closure
|
||||
partsToSelect.add( getAttributeMappings().get( getSubclassPropertyIndex( lazyAttributeDescriptor.getName() ) ) );
|
||||
partsToSelect.add( getAttributeMapping( getSubclassPropertyIndex( lazyAttributeDescriptor.getName() ) ) );
|
||||
}
|
||||
|
||||
if ( partsToSelect.isEmpty() ) {
|
||||
|
@ -2915,8 +2915,8 @@ public abstract class AbstractEntityPersister
|
|||
final Update update = createUpdate().setTableName( getTableName( j ) );
|
||||
|
||||
boolean hasColumns = false;
|
||||
for ( int index = 0; index < attributeMappings.size(); index++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings.get( index );
|
||||
for ( int index = 0; index < attributeMappings.length; index++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings[index];
|
||||
if ( isPropertyOfTable( index, j ) ) {
|
||||
// `attributeMapping` is an attribute of the table we are updating
|
||||
|
||||
|
@ -3039,8 +3039,8 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
final Insert insert = createInsert().setTableName( getTableName( j ) );
|
||||
|
||||
for ( int index = 0; index < attributeMappings.size(); index++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings.get( index );
|
||||
for ( int index = 0; index < attributeMappings.length; index++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings[index];
|
||||
if ( isPropertyOfTable( index, j ) ) {
|
||||
// `attributeMapping` is an attribute of the table we are updating
|
||||
|
||||
|
@ -5117,10 +5117,10 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
else {
|
||||
if ( hasSubclasses() ) {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
for ( int i = 0; i < attributeMappings.length; i++ ) {
|
||||
final Object value = values[i];
|
||||
if ( value != UNFETCHED_PROPERTY ) {
|
||||
final Setter setter = attributeMappings.get( i ).getPropertyAccess().getSetter();
|
||||
final Setter setter = attributeMappings[i].getPropertyAccess().getSetter();
|
||||
setter.set( object, value );
|
||||
}
|
||||
}
|
||||
|
@ -5153,8 +5153,8 @@ public abstract class AbstractEntityPersister
|
|||
final BytecodeEnhancementMetadata enhancementMetadata = entityMetamodel.getBytecodeEnhancementMetadata();
|
||||
final LazyAttributesMetadata lazyAttributesMetadata = enhancementMetadata.getLazyAttributesMetadata();
|
||||
final Object[] values = new Object[ getNumberOfAttributeMappings() ];
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
for ( int i = 0; i < attributeMappings.length; i++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings[i];
|
||||
final AttributeMetadataAccess attributeMetadataAccess = attributeMapping.getAttributeMetadataAccess();
|
||||
if ( ! lazyAttributesMetadata.isLazyAttribute( attributeMapping.getAttributeName() )
|
||||
|| enhancementMetadata.isAttributeLoaded( object, attributeMapping.getAttributeName() ) ) {
|
||||
|
@ -5175,7 +5175,7 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
@Override
|
||||
public Object getPropertyValue(Object object, int i) {
|
||||
return attributeMappings.get( i ).getAttributeMetadataAccess()
|
||||
return attributeMappings[i].getAttributeMetadataAccess()
|
||||
.resolveAttributeMetadata( this )
|
||||
.getPropertyAccess()
|
||||
.getGetter()
|
||||
|
@ -5370,9 +5370,9 @@ public abstract class AbstractEntityPersister
|
|||
return accessOptimizer.getPropertyValues( entity );
|
||||
}
|
||||
|
||||
final Object[] result = new Object[this.attributeMappings.size()];
|
||||
for ( int i = 0; i < this.attributeMappings.size(); i++ ) {
|
||||
result[i] = this.attributeMappings.get( i ).getPropertyAccess().getGetter().getForInsert(
|
||||
final Object[] result = new Object[this.attributeMappings.length];
|
||||
for ( int i = 0; i < this.attributeMappings.length; i++ ) {
|
||||
result[i] = this.attributeMappings[i].getPropertyAccess().getGetter().getForInsert(
|
||||
entity,
|
||||
mergeMap,
|
||||
session
|
||||
|
@ -5668,7 +5668,7 @@ public abstract class AbstractEntityPersister
|
|||
private EntityRowIdMapping rowIdMapping;
|
||||
private EntityDiscriminatorMapping discriminatorMapping;
|
||||
|
||||
private List<AttributeMapping> attributeMappings;
|
||||
private AttributeMapping[] attributeMappings;
|
||||
protected Map<String, AttributeMapping> declaredAttributeMappings = new LinkedHashMap<>();
|
||||
protected List<Fetchable> staticFetchableList;
|
||||
|
||||
|
@ -5676,13 +5676,15 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
@Override
|
||||
public void visitAttributeMappings(Consumer<? super AttributeMapping> action) {
|
||||
attributeMappings.forEach( action );
|
||||
for ( AttributeMapping attributeMapping : attributeMappings ) {
|
||||
action.accept( attributeMapping );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachAttributeMapping(IndexedConsumer<AttributeMapping> consumer) {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
consumer.accept( i, attributeMappings.get( i ) );
|
||||
for ( int i = 0; i < attributeMappings.length; i++ ) {
|
||||
consumer.accept( i, attributeMappings[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5770,7 +5772,7 @@ public abstract class AbstractEntityPersister
|
|||
if ( hasUpdateGeneratedProperties() ) {
|
||||
updateGeneratedValuesProcessor = createGeneratedValuesProcessor( GenerationTiming.UPDATE );
|
||||
}
|
||||
staticFetchableList = new ArrayList<>( attributeMappings.size() );
|
||||
staticFetchableList = new ArrayList<>( attributeMappings.length );
|
||||
visitSubTypeAttributeMappings( attributeMapping -> staticFetchableList.add( attributeMapping ) );
|
||||
return true;
|
||||
}
|
||||
|
@ -5910,13 +5912,11 @@ public abstract class AbstractEntityPersister
|
|||
// in the collected names. iterate here because it is already alphabetical
|
||||
|
||||
final List<SingularAttributeMapping> collectedAttrMappings = new ArrayList<>();
|
||||
this.attributeMappings.forEach(
|
||||
(attributeMapping) -> {
|
||||
if ( attributeNames.contains( attributeMapping.getAttributeName() ) ) {
|
||||
collectedAttrMappings.add( (SingularAttributeMapping) attributeMapping );
|
||||
}
|
||||
}
|
||||
);
|
||||
for ( AttributeMapping attributeMapping : attributeMappings ) {
|
||||
if ( attributeNames.contains( attributeMapping.getAttributeName() ) ) {
|
||||
collectedAttrMappings.add( (SingularAttributeMapping) attributeMapping );
|
||||
}
|
||||
}
|
||||
|
||||
if ( collectedAttrMappings.size() <= 1 ) {
|
||||
throw new MappingException( "Expected multiple natural-id attributes, but found only one: " + getEntityName() );
|
||||
|
@ -6106,12 +6106,12 @@ public abstract class AbstractEntityPersister
|
|||
// force calculation of `attributeMappings`
|
||||
getAttributeMappings();
|
||||
}
|
||||
return attributeMappings.size();
|
||||
return attributeMappings.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeMapping getAttributeMapping(int position) {
|
||||
return attributeMappings.get( position );
|
||||
return attributeMappings[position];
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6134,6 +6134,14 @@ public abstract class AbstractEntityPersister
|
|||
return superMappingType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<EntityMappingType> getSubMappingTypes() {
|
||||
if ( subclassMappingTypes == null ) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return subclassMappingTypes.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTypeOrSuperType(EntityMappingType targetType) {
|
||||
if ( targetType == null ) {
|
||||
|
@ -6534,18 +6542,18 @@ public abstract class AbstractEntityPersister
|
|||
@Override
|
||||
public List<AttributeMapping> getAttributeMappings() {
|
||||
if ( attributeMappings == null ) {
|
||||
attributeMappings = new ArrayList<>();
|
||||
ArrayList<AttributeMapping> attributeMappings = new ArrayList<>();
|
||||
|
||||
if ( superMappingType != null ) {
|
||||
superMappingType.visitAttributeMappings( attributeMappings::add );
|
||||
}
|
||||
|
||||
attributeMappings.addAll( declaredAttributeMappings.values() );
|
||||
|
||||
this.attributeMappings = attributeMappings.toArray(new AttributeMapping[0]);
|
||||
// subclasses? it depends on the usage
|
||||
}
|
||||
|
||||
return attributeMappings;
|
||||
return Arrays.asList( attributeMappings );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6769,7 +6777,9 @@ public abstract class AbstractEntityPersister
|
|||
visitSubTypeAttributeMappings( fetchableConsumer );
|
||||
}
|
||||
else {
|
||||
attributeMappings.forEach( fetchableConsumer );
|
||||
for ( AttributeMapping attributeMapping : attributeMappings ) {
|
||||
fetchableConsumer.accept( attributeMapping );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6785,9 +6795,9 @@ public abstract class AbstractEntityPersister
|
|||
return;
|
||||
}
|
||||
|
||||
final int size = attributeMappings.size();
|
||||
final int size = attributeMappings.length;
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
fetchableConsumer.accept( i, attributeMappings.get( i ) );
|
||||
fetchableConsumer.accept( i, attributeMappings[i] );
|
||||
}
|
||||
if ( treatTargetType.isTypeOrSuperType( this ) ) {
|
||||
if ( subclassMappingTypes != null ) {
|
||||
|
@ -6810,7 +6820,9 @@ public abstract class AbstractEntityPersister
|
|||
public void visitAttributeMappings(
|
||||
Consumer<? super AttributeMapping> action,
|
||||
EntityMappingType targetType) {
|
||||
attributeMappings.forEach( action );
|
||||
for ( AttributeMapping attributeMapping : attributeMappings ) {
|
||||
action.accept( attributeMapping );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6823,9 +6835,8 @@ public abstract class AbstractEntityPersister
|
|||
@Override
|
||||
public int forEachSelectable(int offset, SelectableConsumer selectableConsumer) {
|
||||
int span = 0;
|
||||
final List<AttributeMapping> mappings = getAttributeMappings();
|
||||
for ( int i = 0; i < mappings.size(); i++ ) {
|
||||
span += mappings.get( i ).forEachSelectable( span + offset, selectableConsumer );
|
||||
for ( AttributeMapping attributeMapping : attributeMappings ) {
|
||||
span += attributeMapping.forEachSelectable( span + offset, selectableConsumer );
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.sql.results.graph.entity;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -33,9 +32,10 @@ import org.hibernate.event.spi.PreLoadEvent;
|
|||
import org.hibernate.event.spi.PreLoadEventListener;
|
||||
import org.hibernate.internal.util.NullnessHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.loader.entity.CacheEntityLoaderHelper;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.AttributeMetadata;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityVersionMapping;
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
|
@ -64,6 +64,7 @@ import org.hibernate.type.Type;
|
|||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
|
||||
import static org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer.UNFETCHED_PROPERTY;
|
||||
import static org.hibernate.internal.log.LoggingHelper.toLoggableString;
|
||||
|
||||
/**
|
||||
|
@ -90,7 +91,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
private final DomainResultAssembler versionAssembler;
|
||||
private final DomainResultAssembler<Object> rowIdAssembler;
|
||||
|
||||
private final Map<AttributeMapping, DomainResultAssembler> assemblerMap;
|
||||
private final DomainResultAssembler[][] assemblers;
|
||||
|
||||
// per-row state
|
||||
private EntityPersister concreteDescriptor;
|
||||
|
@ -167,17 +168,21 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
this.rowIdAssembler = null;
|
||||
}
|
||||
|
||||
final Collection<EntityMappingType> subMappingTypes = rootEntityDescriptor.getSubMappingTypes();
|
||||
assemblers = new DomainResultAssembler[subMappingTypes.size() + 1][];
|
||||
assemblers[rootEntityDescriptor.getSubclassId()] = new DomainResultAssembler[rootEntityDescriptor.getNumberOfFetchables()];
|
||||
|
||||
for ( EntityMappingType subMappingType : subMappingTypes ) {
|
||||
assemblers[subMappingType.getSubclassId()] = new DomainResultAssembler[subMappingType.getNumberOfFetchables()];
|
||||
}
|
||||
|
||||
final int size = entityDescriptor.getNumberOfFetchables();
|
||||
assemblerMap = new IdentityHashMap<>( CollectionHelper.determineProperSizing( size ) );
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
final AttributeMapping attributeMapping = (AttributeMapping) entityDescriptor.getFetchable( i );
|
||||
|
||||
// todo (6.0) : somehow we need to track whether all state is loaded/resolved
|
||||
// note that lazy proxies or uninitialized collections count against
|
||||
// that in the affirmative
|
||||
|
||||
final Fetch fetch = resultDescriptor.findFetch( attributeMapping );
|
||||
|
||||
final DomainResultAssembler<?> stateAssembler;
|
||||
if ( fetch == null ) {
|
||||
stateAssembler = new NullValueAssembler<>(
|
||||
|
@ -188,7 +193,12 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
stateAssembler = fetch.createAssembler( this, creationState );
|
||||
}
|
||||
|
||||
assemblerMap.put( attributeMapping, stateAssembler );
|
||||
final int stateArrayPosition = attributeMapping.getStateArrayPosition();
|
||||
final EntityMappingType declaringType = (EntityMappingType) attributeMapping.getDeclaringType();
|
||||
assemblers[declaringType.getSubclassId()][stateArrayPosition] = stateAssembler;
|
||||
for ( EntityMappingType subMappingType : declaringType.getSubMappingTypes() ) {
|
||||
assemblers[subMappingType.getSubclassId()][stateArrayPosition] = stateAssembler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,25 +207,24 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
Object[] source,
|
||||
Object[] target,
|
||||
EntityPersister concreteDescriptor) {
|
||||
containerDescriptor.visitAttributeMappings(
|
||||
attributeMapping -> {
|
||||
if ( attributeMapping.getAttributeMetadataAccess().resolveAttributeMetadata( concreteDescriptor ).isUpdatable() ) {
|
||||
final int position = attributeMapping.getStateArrayPosition();
|
||||
Object result;
|
||||
if ( source[position] == LazyPropertyInitializer.UNFETCHED_PROPERTY
|
||||
|| source[position] == PropertyAccessStrategyBackRefImpl.UNKNOWN ) {
|
||||
result = source[position];
|
||||
}
|
||||
else {
|
||||
result = attributeMapping.getAttributeMetadataAccess()
|
||||
.resolveAttributeMetadata(null)
|
||||
.getMutabilityPlan()
|
||||
.deepCopy( source[position] );
|
||||
}
|
||||
target[position] = result;
|
||||
}
|
||||
final int numberOfAttributeMappings = containerDescriptor.getNumberOfAttributeMappings();
|
||||
for ( int i = 0; i < numberOfAttributeMappings; i++ ) {
|
||||
final AttributeMapping attributeMapping = containerDescriptor.getAttributeMapping( i );
|
||||
final AttributeMetadata attributeMetadata = attributeMapping.getAttributeMetadataAccess()
|
||||
.resolveAttributeMetadata( concreteDescriptor );
|
||||
if ( attributeMetadata.isUpdatable() ) {
|
||||
final int position = attributeMapping.getStateArrayPosition();
|
||||
Object result;
|
||||
if ( source[position] == LazyPropertyInitializer.UNFETCHED_PROPERTY
|
||||
|| source[position] == PropertyAccessStrategyBackRefImpl.UNKNOWN ) {
|
||||
result = source[position];
|
||||
}
|
||||
);
|
||||
else {
|
||||
result = attributeMetadata.getMutabilityPlan().deepCopy( source[position] );
|
||||
}
|
||||
target[position] = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -702,10 +711,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
|
||||
entityDescriptor.setIdentifier( toInitialize, entityIdentifier, session );
|
||||
|
||||
resolvedEntityState = concreteDescriptor.extractConcreteTypeStateValues(
|
||||
assemblerMap,
|
||||
rowProcessingState
|
||||
);
|
||||
resolvedEntityState = extractConcreteTypeStateValues( rowProcessingState );
|
||||
|
||||
if ( isPersistentAttributeInterceptable( toInitialize ) ) {
|
||||
PersistentAttributeInterceptor persistentAttributeInterceptor = asPersistentAttributeInterceptable( toInitialize ).$$_hibernate_getInterceptor();
|
||||
|
@ -900,6 +906,24 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
}
|
||||
}
|
||||
|
||||
private Object[] extractConcreteTypeStateValues(RowProcessingState rowProcessingState) {
|
||||
final Object[] values = new Object[concreteDescriptor.getNumberOfAttributeMappings()];
|
||||
final DomainResultAssembler[] concreteAssemblers = assemblers[concreteDescriptor.getSubclassId()];
|
||||
for ( int i = 0; i < values.length; i++ ) {
|
||||
final DomainResultAssembler assembler = concreteAssemblers[i];
|
||||
final Object value;
|
||||
if ( assembler == null ) {
|
||||
value = UNFETCHED_PROPERTY;
|
||||
}
|
||||
else {
|
||||
value = assembler.assemble( rowProcessingState );
|
||||
}
|
||||
|
||||
values[i] = value;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private boolean skipInitialization(
|
||||
Object toInitialize,
|
||||
RowProcessingState rowProcessingState,
|
||||
|
|
|
@ -74,6 +74,7 @@ public class EntityMetamodel implements Serializable {
|
|||
private final String rootName;
|
||||
private EntityType entityType;
|
||||
|
||||
private final int subclassId;
|
||||
private final IdentifierProperty identifierAttribute;
|
||||
private final boolean versioned;
|
||||
|
||||
|
@ -151,6 +152,7 @@ public class EntityMetamodel implements Serializable {
|
|||
// Improves performance of EntityKey#equals by avoiding content check in String#equals
|
||||
name = persistentClass.getEntityName().intern();
|
||||
rootName = persistentClass.getRootClass().getEntityName().intern();
|
||||
subclassId = persistentClass.getSubclassId();
|
||||
|
||||
identifierAttribute = PropertyFactory.buildIdentifierAttribute(
|
||||
persistentClass,
|
||||
|
@ -892,6 +894,10 @@ public class EntityMetamodel implements Serializable {
|
|||
return rootName;
|
||||
}
|
||||
|
||||
public int getSubclassId() {
|
||||
return subclassId;
|
||||
}
|
||||
|
||||
public EntityType getEntityType() {
|
||||
if ( entityType == null ) {
|
||||
entityType = new ManyToOneType( name, getSessionFactory().getTypeConfiguration() );
|
||||
|
|
Loading…
Reference in New Issue