improvements to how discriminators are handled by AbstractEntityPersister

This commit is contained in:
Gavin 2022-12-24 14:55:20 +01:00 committed by Gavin King
parent b1e2eca53e
commit e918f92f48
10 changed files with 171 additions and 205 deletions

View File

@ -641,9 +641,11 @@ public class EntityBinder {
processDiscriminatorOptions(); processDiscriminatorOptions();
final AnnotatedDiscriminatorColumn discriminatorColumn = processSingleTableDiscriminatorProperties( inheritanceState ); final AnnotatedDiscriminatorColumn discriminatorColumn = processSingleTableDiscriminatorProperties( inheritanceState );
if ( !inheritanceState.hasParents() ) { // todo : sucks that this is separate from RootClass distinction if ( !inheritanceState.hasParents() ) { // todo : sucks that this is separate from RootClass distinction
final RootClass rootClass = (RootClass) persistentClass;
if ( inheritanceState.hasSiblings() if ( inheritanceState.hasSiblings()
|| discriminatorColumn != null && !discriminatorColumn.isImplicit() ) { || discriminatorColumn != null && !discriminatorColumn.isImplicit() ) {
bindDiscriminatorColumnToRootPersistentClass( (RootClass) persistentClass, discriminatorColumn, holder ); bindDiscriminatorColumnToRootPersistentClass(rootClass, discriminatorColumn, holder );
rootClass.setForceDiscriminator( isForceDiscriminatorInSelects() );
} }
} }
} }
@ -668,13 +670,15 @@ public class EntityBinder {
final AnnotatedDiscriminatorColumn discriminatorColumn = processJoinedDiscriminatorProperties( state ); final AnnotatedDiscriminatorColumn discriminatorColumn = processJoinedDiscriminatorProperties( state );
if ( !state.hasParents() ) { // todo : sucks that this is separate from RootClass distinction if ( !state.hasParents() ) { // todo : sucks that this is separate from RootClass distinction
final RootClass rootClass = (RootClass) persistentClass;
// the class we're processing is the root of the hierarchy, so // the class we're processing is the root of the hierarchy, so
// let's see if we had a discriminator column (it's perfectly // let's see if we had a discriminator column (it's perfectly
// valid for joined inheritance to not have a discriminator) // valid for joined inheritance to not have a discriminator)
if ( discriminatorColumn != null ) { if ( discriminatorColumn != null ) {
// we do have a discriminator column // we do have a discriminator column
if ( state.hasSiblings() || !discriminatorColumn.isImplicit() ) { if ( state.hasSiblings() || !discriminatorColumn.isImplicit() ) {
bindDiscriminatorColumnToRootPersistentClass( (RootClass) persistentClass, discriminatorColumn, holder ); bindDiscriminatorColumnToRootPersistentClass(rootClass, discriminatorColumn, holder );
rootClass.setForceDiscriminator( isForceDiscriminatorInSelects() );
} }
} }
} }
@ -750,7 +754,6 @@ public class EntityBinder {
new NullableDiscriminatorColumnSecondPass( rootClass.getEntityName() ) new NullableDiscriminatorColumnSecondPass( rootClass.getEntityName() )
); );
} }
rootClass.setForceDiscriminator( isForceDiscriminatorInSelects() );
if ( insertableDiscriminator != null ) { if ( insertableDiscriminator != null ) {
rootClass.setDiscriminatorInsertable( insertableDiscriminator ); rootClass.setDiscriminatorInsertable( insertableDiscriminator );
} }

View File

@ -11,7 +11,6 @@ import java.lang.reflect.Constructor;
import org.hibernate.InstantiationException; import org.hibernate.InstantiationException;
import org.hibernate.PropertyNotFoundException; import org.hibernate.PropertyNotFoundException;
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor; import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;

View File

@ -48,29 +48,30 @@ public class CaseStatementDiscriminatorMappingImpl extends AbstractDiscriminator
int[] notNullColumnTableNumbers, int[] notNullColumnTableNumbers,
String[] notNullColumnNames, String[] notNullColumnNames,
String[] discriminatorValues, String[] discriminatorValues,
boolean[] discriminatorAbstract,
Map<String,String> subEntityNameByTableName, Map<String,String> subEntityNameByTableName,
DiscriminatorType<?> incomingDiscriminatorType, DiscriminatorType<?> incomingDiscriminatorType,
Map<Object, DiscriminatorValueDetails> valueMappings, Map<Object, DiscriminatorValueDetails> valueMappings,
MappingModelCreationProcess creationProcess) { MappingModelCreationProcess creationProcess) {
super( entityDescriptor, incomingDiscriminatorType, valueMappings, creationProcess ); super( entityDescriptor, incomingDiscriminatorType, valueMappings, creationProcess );
for ( int i = 0; i < discriminatorValues.length; i++ ) { for ( int i = 0; i < discriminatorValues.length; i++ ) {
final String tableName = tableNames[notNullColumnTableNumbers[i]]; if ( !discriminatorAbstract[i] ) {
final String subEntityName = subEntityNameByTableName.get( tableName ); final String tableName = tableNames[notNullColumnTableNumbers[i]];
final String oneSubEntityColumn = notNullColumnNames[i]; final String subEntityName = subEntityNameByTableName.get( tableName );
final String oneSubEntityColumn = notNullColumnNames[i];
final String rawDiscriminatorValue = discriminatorValues[i]; final String discriminatorValue = discriminatorValues[i];
final Object discriminatorValue = getUnderlyingJdbcMappingType().getJavaTypeDescriptor().wrap( rawDiscriminatorValue, null ); tableDiscriminatorDetailsMap.put(
tableName,
tableDiscriminatorDetailsMap.put( new TableDiscriminatorDetails(
tableName, tableName,
new TableDiscriminatorDetails( oneSubEntityColumn,
tableName, getUnderlyingJdbcMappingType().getJavaTypeDescriptor()
oneSubEntityColumn, .wrap( discriminatorValue, null ),
discriminatorValue, subEntityName
subEntityName )
) );
); }
} }
} }

View File

@ -26,6 +26,7 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -111,7 +112,6 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.FilterAliasGenerator; import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.FilterHelper; import org.hibernate.internal.FilterHelper;
import org.hibernate.internal.util.LazyValue; import org.hibernate.internal.util.LazyValue;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
@ -191,6 +191,7 @@ import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
import org.hibernate.metamodel.model.domain.NavigableRole; import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.spi.EntityInstantiator; import org.hibernate.metamodel.spi.EntityInstantiator;
import org.hibernate.metamodel.spi.EntityRepresentationStrategy; import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.mutation.DeleteCoordinator; import org.hibernate.persister.entity.mutation.DeleteCoordinator;
@ -203,7 +204,6 @@ import org.hibernate.persister.entity.mutation.UpdateCoordinatorStandard;
import org.hibernate.persister.internal.ImmutableAttributeMappingList; import org.hibernate.persister.internal.ImmutableAttributeMappingList;
import org.hibernate.persister.internal.SqlFragmentPredicate; import org.hibernate.persister.internal.SqlFragmentPredicate;
import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.hibernate.query.SemanticException; import org.hibernate.query.SemanticException;
@ -275,6 +275,7 @@ import org.hibernate.type.EntityType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.MutabilityPlan; import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import static java.util.Collections.emptySet; import static java.util.Collections.emptySet;
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable; import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
@ -284,6 +285,7 @@ import static org.hibernate.engine.internal.ManagedTypeHelper.processIfSelfDirti
import static org.hibernate.engine.internal.Versioning.isVersionIncrementRequired; import static org.hibernate.engine.internal.Versioning.isVersionIncrementRequired;
import static org.hibernate.generator.EventType.INSERT; import static org.hibernate.generator.EventType.INSERT;
import static org.hibernate.generator.EventType.UPDATE; import static org.hibernate.generator.EventType.UPDATE;
import static org.hibernate.internal.util.ReflectHelper.isAbstractClass;
import static org.hibernate.internal.util.StringHelper.isEmpty; import static org.hibernate.internal.util.StringHelper.isEmpty;
import static org.hibernate.internal.util.collections.ArrayHelper.contains; import static org.hibernate.internal.util.collections.ArrayHelper.contains;
import static org.hibernate.internal.util.collections.ArrayHelper.to2DStringArray; import static org.hibernate.internal.util.collections.ArrayHelper.to2DStringArray;
@ -297,6 +299,7 @@ import static org.hibernate.internal.util.collections.CollectionHelper.toSmallLi
import static org.hibernate.metamodel.RepresentationMode.POJO; import static org.hibernate.metamodel.RepresentationMode.POJO;
import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR; import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR;
import static org.hibernate.persister.entity.DiscriminatorHelper.NULL_DISCRIMINATOR; import static org.hibernate.persister.entity.DiscriminatorHelper.NULL_DISCRIMINATOR;
import static org.hibernate.persister.entity.DiscriminatorHelper.discriminatorLiteral;
import static org.hibernate.pretty.MessageHelper.infoString; import static org.hibernate.pretty.MessageHelper.infoString;
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey; import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
@ -452,7 +455,7 @@ public abstract class AbstractEntityPersister
protected ReflectionOptimizer.AccessOptimizer accessOptimizer; protected ReflectionOptimizer.AccessOptimizer accessOptimizer;
private final String[] fullDiscriminatorSQLValues; // private final String[] fullDiscriminatorSQLValues;
private final Object[] fullDiscriminatorValues; private final Object[] fullDiscriminatorValues;
/** /**
@ -800,36 +803,36 @@ public abstract class AbstractEntityPersister
&& shouldInvalidateCache( bootDescriptor, creationContext ); && shouldInvalidateCache( bootDescriptor, creationContext );
final List<Object> values = new ArrayList<>(); final List<Object> values = new ArrayList<>();
final List<String> sqlValues = new ArrayList<>(); // final List<String> sqlValues = new ArrayList<>();
if ( bootDescriptor.isPolymorphic() && bootDescriptor.getDiscriminator() != null ) { if ( bootDescriptor.isPolymorphic() && bootDescriptor.getDiscriminator() != null ) {
if ( !getEntityMetamodel().isAbstract() ) { if ( !getEntityMetamodel().isAbstract() ) {
Object discriminatorValue = DiscriminatorHelper.getDiscriminatorValue( bootDescriptor ); values.add( DiscriminatorHelper.getDiscriminatorValue( bootDescriptor ) );
String discriminatorSQLValue = DiscriminatorHelper.getDiscriminatorSQLValue( bootDescriptor, dialect, factory ); // sqlValues.add( DiscriminatorHelper.getDiscriminatorSQLValue( bootDescriptor, dialect, factory ) );
values.add( discriminatorValue );
sqlValues.add( discriminatorSQLValue );
} }
final List<Subclass> subclasses = bootDescriptor.getSubclasses(); final List<Subclass> subclasses = bootDescriptor.getSubclasses();
for ( int k = 0; k < subclasses.size(); k++ ) { for ( int k = 0; k < subclasses.size(); k++ ) {
Subclass subclass = subclasses.get( k ); final Subclass subclass = subclasses.get( k );
//copy/paste from EntityMetamodel: //copy/paste from EntityMetamodel:
boolean subclassAbstract = subclass.isAbstract() == null if ( !isAbstract( subclass ) ) {
? subclass.hasPojoRepresentation() && ReflectHelper.isAbstractClass( subclass.getMappedClass() ) values.add( DiscriminatorHelper.getDiscriminatorValue( subclass ) );
: subclass.isAbstract(); // sqlValues.add( DiscriminatorHelper.getDiscriminatorSQLValue( subclass, dialect, factory ) );
if ( !subclassAbstract ) {
Object subclassDiscriminatorValue = DiscriminatorHelper.getDiscriminatorValue( subclass );
values.add( subclassDiscriminatorValue );
sqlValues.add( DiscriminatorHelper.getDiscriminatorSQLValue( subclass, dialect, factory ) );
} }
} }
} }
fullDiscriminatorSQLValues = toStringArray( sqlValues ); // fullDiscriminatorSQLValues = toStringArray( sqlValues );
fullDiscriminatorValues = toObjectArray( values ); fullDiscriminatorValues = toObjectArray( values );
} }
static boolean isAbstract(PersistentClass subclass) {
final Boolean knownAbstract = subclass.isAbstract();
return knownAbstract == null
? subclass.hasPojoRepresentation() && isAbstractClass( subclass.getMappedClass() )
: knownAbstract;
}
private boolean shouldUseReferenceCacheEntries() { private boolean shouldUseReferenceCacheEntries() {
// Check if we can use Reference Cached entities in 2lc // Check if we can use Reference Cached entities in 2lc
// todo : should really validate that the cache access type is read-only // todo : should really validate that the cache access type is read-only
@ -2225,12 +2228,9 @@ public abstract class AbstractEntityPersister
String[] templates = getSubclassPropertyFormulaTemplateClosure()[i]; String[] templates = getSubclassPropertyFormulaTemplateClosure()[i];
String[] result = new String[cols.length]; String[] result = new String[cols.length];
for ( int j = 0; j < cols.length; j++ ) { for ( int j = 0; j < cols.length; j++ ) {
if ( cols[j] == null ) { result[j] = cols[j] == null
result[j] = StringHelper.replace( templates[j], Template.TEMPLATE, alias ); ? StringHelper.replace( templates[j], Template.TEMPLATE, alias )
} : StringHelper.qualify( alias, cols[j] );
else {
result[j] = StringHelper.qualify( alias, cols[j] );
}
} }
return result; return result;
} }
@ -2927,6 +2927,8 @@ public abstract class AbstractEntityPersister
} }
} }
public abstract Map<Object, String> getSubclassByDiscriminatorValue();
protected abstract boolean needsDiscriminator(); protected abstract boolean needsDiscriminator();
protected boolean isDiscriminatorFormula() { protected boolean isDiscriminatorFormula() {
@ -4929,7 +4931,7 @@ public abstract class AbstractEntityPersister
else { else {
rowIdMapping = creationProcess.processSubPart( rowIdMapping = creationProcess.processSubPart(
rowIdName, rowIdName,
(role, process) -> new EntityRowIdMappingImpl( rowIdName, this.getTableName(), this ) (role, process) -> new EntityRowIdMappingImpl( rowIdName, getTableName(), this )
); );
} }
@ -5064,7 +5066,7 @@ public abstract class AbstractEntityPersister
protected EntityDiscriminatorMapping generateDiscriminatorMapping( protected EntityDiscriminatorMapping generateDiscriminatorMapping(
PersistentClass bootEntityDescriptor, PersistentClass bootEntityDescriptor,
MappingModelCreationProcess modelCreationProcess) { MappingModelCreationProcess modelCreationProcess) {
if ( getDiscriminatorType() == null) { if ( getDiscriminatorType() == null ) {
return null; return null;
} }
else { else {
@ -5074,7 +5076,7 @@ public abstract class AbstractEntityPersister
final Integer precision; final Integer precision;
final Integer scale; final Integer scale;
if ( getDiscriminatorFormulaTemplate() == null ) { if ( getDiscriminatorFormulaTemplate() == null ) {
Column column = bootEntityDescriptor.getDiscriminator() == null final Column column = bootEntityDescriptor.getDiscriminator() == null
? null ? null
: bootEntityDescriptor.getDiscriminator().getColumns().get( 0 ); : bootEntityDescriptor.getDiscriminator().getColumns().get( 0 );
discriminatorColumnExpression = getDiscriminatorColumnReaders(); discriminatorColumnExpression = getDiscriminatorColumnReaders();
@ -5098,7 +5100,7 @@ public abstract class AbstractEntityPersister
precision = null; precision = null;
scale = null; scale = null;
} }
return new ExplicitColumnDiscriminatorMappingImpl ( return new ExplicitColumnDiscriminatorMappingImpl(
this, this,
getTableName(), getTableName(),
discriminatorColumnExpression, discriminatorColumnExpression,
@ -5106,16 +5108,38 @@ public abstract class AbstractEntityPersister
isPhysicalDiscriminator(), isPhysicalDiscriminator(),
columnDefinition, length, precision, scale, columnDefinition, length, precision, scale,
(DiscriminatorType<?>) getTypeDiscriminatorMetadata().getResolutionType(), (DiscriminatorType<?>) getTypeDiscriminatorMetadata().getResolutionType(),
buildDiscriminatorValueMappings( bootEntityDescriptor, modelCreationProcess ), buildDiscriminatorValueMappings( modelCreationProcess ),
modelCreationProcess modelCreationProcess
); );
} }
} }
protected abstract Map<Object, DiscriminatorValueDetails> buildDiscriminatorValueMappings( @Override
PersistentClass bootEntityDescriptor, public abstract BasicType<?> getDiscriminatorType();
MappingModelCreationProcess modelCreationProcess);
protected Map<Object, DiscriminatorValueDetails> buildDiscriminatorValueMappings(
MappingModelCreationProcess modelCreationProcess) {
final MappingMetamodelImplementor mappingModel = modelCreationProcess.getCreationContext()
.getSessionFactory()
.getMappingMetamodel();
//noinspection unchecked
final JdbcLiteralFormatter<Object> jdbcLiteralFormatter =
(JdbcLiteralFormatter<Object>) getDiscriminatorType().getJdbcLiteralFormatter();
final Dialect dialect = modelCreationProcess.getCreationContext()
.getSessionFactory().getJdbcServices().getDialect();
final Map<Object, DiscriminatorValueDetails> valueMappings = new ConcurrentHashMap<>();
getSubclassByDiscriminatorValue().forEach( (value, entityName) -> {
final DiscriminatorValueDetailsImpl valueMapping = new DiscriminatorValueDetailsImpl(
value,
discriminatorLiteral( jdbcLiteralFormatter, dialect, value ),
mappingModel.findEntityDescriptor( entityName )
);
valueMappings.put( value, valueMapping );
} );
return valueMappings;
}
protected EntityVersionMapping generateVersionMapping( protected EntityVersionMapping generateVersionMapping(
Supplier<?> templateInstanceCreator, Supplier<?> templateInstanceCreator,

View File

@ -38,10 +38,7 @@ public class DiscriminatorHelper {
} }
} }
static String getDiscriminatorSQLValue( static String getDiscriminatorSQLValue(PersistentClass persistentClass, Dialect dialect) {
PersistentClass persistentClass,
Dialect dialect,
SessionFactoryImplementor factory) {
if ( persistentClass.isDiscriminatorValueNull() ) { if ( persistentClass.isDiscriminatorValueNull() ) {
return InFragment.NULL; return InFragment.NULL;
} }
@ -49,11 +46,7 @@ public class DiscriminatorHelper {
return InFragment.NOT_NULL; return InFragment.NOT_NULL;
} }
else { else {
return discriminatorSqlLiteral( return discriminatorSqlLiteral( getDiscriminatorType( persistentClass ), persistentClass, dialect );
getDiscriminatorType( persistentClass ),
persistentClass,
dialect
);
} }
} }
@ -62,7 +55,7 @@ public class DiscriminatorHelper {
try { try {
return discriminatorType.getJavaTypeDescriptor().fromString( persistentClass.getDiscriminatorValue() ); return discriminatorType.getJavaTypeDescriptor().fromString( persistentClass.getDiscriminatorValue() );
} }
catch (Exception e) { catch ( Exception e ) {
throw new MappingException( "Could not parse discriminator value", e ); throw new MappingException( "Could not parse discriminator value", e );
} }
} }
@ -90,7 +83,7 @@ public class DiscriminatorHelper {
); );
} }
public static <T> String jdbcLiteral( private static <T> String jdbcLiteral(
T value, T value,
JdbcLiteralFormatter<T> formatter, JdbcLiteralFormatter<T> formatter,
Dialect dialect) { Dialect dialect) {
@ -101,4 +94,11 @@ public class DiscriminatorHelper {
throw new MappingException( "Could not format discriminator value to SQL string", e ); throw new MappingException( "Could not format discriminator value to SQL string", e );
} }
} }
static String discriminatorLiteral(JdbcLiteralFormatter<Object> formatter, Dialect dialect, Object value) {
return value == NULL_DISCRIMINATOR || value == NOT_NULL_DISCRIMINATOR
? null
: jdbcLiteral( value, formatter, dialect );
}
} }

View File

@ -14,7 +14,6 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
@ -29,7 +28,6 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.DynamicFilterAliasGenerator; import org.hibernate.internal.DynamicFilterAliasGenerator;
import org.hibernate.internal.FilterAliasGenerator; import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.jdbc.Expectation; import org.hibernate.jdbc.Expectation;
import org.hibernate.mapping.Column; import org.hibernate.mapping.Column;
import org.hibernate.mapping.Formula; import org.hibernate.mapping.Formula;
@ -43,7 +41,6 @@ import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping.DiscriminatorValueDetails;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.EntityVersionMapping; import org.hibernate.metamodel.mapping.EntityVersionMapping;
@ -71,13 +68,15 @@ import org.hibernate.type.BasicType;
import org.hibernate.type.CompositeType; import org.hibernate.type.CompositeType;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import static java.util.Collections.emptyMap; import static java.util.Collections.emptyMap;
import static org.hibernate.internal.util.collections.ArrayHelper.to2DStringArray; import static org.hibernate.internal.util.collections.ArrayHelper.to2DStringArray;
import static org.hibernate.internal.util.collections.ArrayHelper.toIntArray;
import static org.hibernate.internal.util.collections.ArrayHelper.toStringArray; import static org.hibernate.internal.util.collections.ArrayHelper.toStringArray;
import static org.hibernate.internal.util.collections.CollectionHelper.linkedMapOfSize;
import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize;
import static org.hibernate.jdbc.Expectations.appropriateExpectation; import static org.hibernate.jdbc.Expectations.appropriateExpectation;
import static org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper.buildEncapsulatedCompositeIdentifierMapping; import static org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper.buildEncapsulatedCompositeIdentifierMapping;
import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR; import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR;
@ -143,6 +142,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
// values in the outer join using an SQL CASE // values in the outer join using an SQL CASE
private final Map<Object,String> subclassesByDiscriminatorValue = new HashMap<>(); private final Map<Object,String> subclassesByDiscriminatorValue = new HashMap<>();
private final String[] discriminatorValues; private final String[] discriminatorValues;
private final boolean[] discriminatorAbstract;
private final String[] notNullColumnNames; private final String[] notNullColumnNames;
private final int[] notNullColumnTableNumbers; private final int[] notNullColumnTableNumbers;
@ -210,7 +210,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
} }
discriminatorType = DiscriminatorHelper.getDiscriminatorType( persistentClass ); discriminatorType = DiscriminatorHelper.getDiscriminatorType( persistentClass );
discriminatorValue = DiscriminatorHelper.getDiscriminatorValue( persistentClass ); discriminatorValue = DiscriminatorHelper.getDiscriminatorValue( persistentClass );
discriminatorSQLString = DiscriminatorHelper.getDiscriminatorSQLValue( persistentClass, dialect, factory ); discriminatorSQLString = DiscriminatorHelper.getDiscriminatorSQLValue( persistentClass, dialect );
} }
else { else {
explicitDiscriminatorColumnName = null; explicitDiscriminatorColumnName = null;
@ -528,8 +528,8 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
} }
} }
subclassColumnTableNumberClosure = ArrayHelper.toIntArray( columnTableNumbers ); subclassColumnTableNumberClosure = toIntArray( columnTableNumbers );
subclassPropertyTableNumberClosure = ArrayHelper.toIntArray( propTableNumbers ); subclassPropertyTableNumberClosure = toIntArray( propTableNumbers );
// subclassFormulaTableNumberClosure = ArrayHelper.toIntArray( formulaTableNumbers ); // subclassFormulaTableNumberClosure = ArrayHelper.toIntArray( formulaTableNumbers );
subclassColumnClosure = toStringArray( columns ); subclassColumnClosure = toStringArray( columns );
@ -544,19 +544,21 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
discriminatorValuesByTableName = emptyMap(); discriminatorValuesByTableName = emptyMap();
discriminatorColumnNameByTableName = emptyMap(); discriminatorColumnNameByTableName = emptyMap();
discriminatorValues = null; discriminatorValues = null;
discriminatorAbstract = null;
notNullColumnTableNumbers = null; notNullColumnTableNumbers = null;
notNullColumnNames = null; notNullColumnNames = null;
} }
else { else {
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() ); subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
discriminatorValuesByTableName = CollectionHelper.linkedMapOfSize( subclassSpan + 1 ); discriminatorValuesByTableName = linkedMapOfSize( subclassSpan + 1 );
discriminatorColumnNameByTableName = CollectionHelper.linkedMapOfSize( subclassSpan + 1 ); discriminatorColumnNameByTableName = linkedMapOfSize( subclassSpan + 1 );
subclassNameByTableName = CollectionHelper.mapOfSize( subclassSpan + 1 ); subclassNameByTableName = mapOfSize( subclassSpan + 1 );
Table table = persistentClass.getTable(); Table table = persistentClass.getTable();
discriminatorValues = new String[subclassSpan]; discriminatorValues = new String[subclassSpan];
initDiscriminatorProperties( dialect, subclassSpanMinusOne, table, discriminatorValue ); discriminatorAbstract = new boolean[subclassSpan];
initDiscriminatorProperties( dialect, subclassSpanMinusOne, table, discriminatorValue, isAbstract( persistentClass) );
notNullColumnTableNumbers = new int[subclassSpan]; notNullColumnTableNumbers = new int[subclassSpan];
final int id = getTableId( final int id = getTableId(
@ -580,7 +582,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
// persisters for a class hierarchy, so that the use of // persisters for a class hierarchy, so that the use of
// "foo.class = Bar" works in HQL // "foo.class = Bar" works in HQL
: subclass.getSubclassId(); : subclass.getSubclassId();
initDiscriminatorProperties( dialect, k, subclassTable, discriminatorValue ); initDiscriminatorProperties( dialect, k, subclassTable, discriminatorValue, isAbstract( subclass ) );
subclassesByDiscriminatorValue.put( discriminatorValue, subclass.getEntityName() ); subclassesByDiscriminatorValue.put( discriminatorValue, subclass.getEntityName() );
int tableId = getTableId( int tableId = getTableId(
subclassTable.getQualifiedName( factory.getSqlStringGenerationContext() ), subclassTable.getQualifiedName( factory.getSqlStringGenerationContext() ),
@ -600,12 +602,18 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
} }
private void initDiscriminatorProperties(Dialect dialect, int k, Table table, Object discriminatorValue) { private void initDiscriminatorProperties(Dialect dialect, int k, Table table, Object discriminatorValue, boolean isAbstract) {
final String tableName = determineTableName( table ); final String tableName = determineTableName( table );
final String columnName = table.getPrimaryKey().getColumn( 0 ).getQuotedName( dialect ); final String columnName = table.getPrimaryKey().getColumn( 0 ).getQuotedName( dialect );
discriminatorValuesByTableName.put( tableName, discriminatorValue ); discriminatorValuesByTableName.put( tableName, discriminatorValue );
discriminatorColumnNameByTableName.put( tableName, columnName ); discriminatorColumnNameByTableName.put( tableName, columnName );
discriminatorValues[k] = discriminatorValue.toString(); discriminatorValues[k] = discriminatorValue.toString();
discriminatorAbstract[k] = isAbstract;
}
@Override
public Map<Object, String> getSubclassByDiscriminatorValue() {
return subclassesByDiscriminatorValue;
} }
/** /**
@ -815,7 +823,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
} }
@Override @Override
public Type getDiscriminatorType() { public BasicType<?> getDiscriminatorType() {
return discriminatorType; return discriminatorType;
} }
@ -862,35 +870,6 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
} }
} }
@Override
protected Map<Object, DiscriminatorValueDetails> buildDiscriminatorValueMappings(
PersistentClass bootEntityDescriptor,
MappingModelCreationProcess modelCreationProcess) {
final MappingMetamodelImplementor mappingModel = modelCreationProcess.getCreationContext()
.getSessionFactory()
.getMappingMetamodel();
//noinspection unchecked
final JdbcLiteralFormatter<Object> jdbcLiteralFormatter =
(JdbcLiteralFormatter<Object>) discriminatorType.getJdbcLiteralFormatter();
final Dialect dialect = modelCreationProcess.getCreationContext()
.getSessionFactory().getJdbcServices().getDialect();
final Map<Object, DiscriminatorValueDetails> valueMappings = new ConcurrentHashMap<>();
subclassesByDiscriminatorValue.forEach( (value, entityName) -> {
final String jdbcLiteral = value == NULL_DISCRIMINATOR || value == NOT_NULL_DISCRIMINATOR
? null
: jdbcLiteralFormatter.toJdbcLiteral( value, dialect, null );
final DiscriminatorValueDetailsImpl valueMapping = new DiscriminatorValueDetailsImpl(
value,
jdbcLiteral,
mappingModel.findEntityDescriptor( entityName )
);
valueMappings.put( value, valueMapping );
} );
return valueMappings;
}
@Override @Override
public void addDiscriminatorToInsertGroup(MutationGroupBuilder insertGroupBuilder) { public void addDiscriminatorToInsertGroup(MutationGroupBuilder insertGroupBuilder) {
if ( explicitDiscriminatorColumnName != null ) { if ( explicitDiscriminatorColumnName != null ) {
@ -1265,31 +1244,33 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
if ( superMappingType != null ) { if ( superMappingType != null ) {
return superMappingType.getDiscriminatorMapping(); return superMappingType.getDiscriminatorMapping();
} }
else if ( hasSubclasses() ) {
if ( hasSubclasses() ) {
final String formula = getDiscriminatorFormulaTemplate(); final String formula = getDiscriminatorFormulaTemplate();
if ( explicitDiscriminatorColumnName != null || formula != null ) { if ( explicitDiscriminatorColumnName != null || formula != null ) {
// even though this is a joined-hierarchy the user has defined an // even though this is a JOINED hierarchy the user has defined an
// explicit discriminator column - so we can use the normal // explicit discriminator column - so we can use the normal
// discriminator mapping // discriminator mapping
return super.generateDiscriminatorMapping( bootEntityDescriptor, modelCreationProcess ); return super.generateDiscriminatorMapping( bootEntityDescriptor, modelCreationProcess );
} }
else {
// otherwise, we need to use the case-statement approach // otherwise, we need to use the case approach
return new CaseStatementDiscriminatorMappingImpl( return new CaseStatementDiscriminatorMappingImpl(
this, this,
subclassTableNameClosure, subclassTableNameClosure,
notNullColumnTableNumbers, notNullColumnTableNumbers,
notNullColumnNames, notNullColumnNames,
discriminatorValues, discriminatorValues,
subclassNameByTableName, discriminatorAbstract,
(DiscriminatorType<?>) getTypeDiscriminatorMetadata().getResolutionType(), subclassNameByTableName,
buildDiscriminatorValueMappings( bootEntityDescriptor, modelCreationProcess ), (DiscriminatorType<?>) getTypeDiscriminatorMetadata().getResolutionType(),
modelCreationProcess buildDiscriminatorValueMappings( modelCreationProcess ),
); modelCreationProcess
);
}
}
else {
return null;
} }
return null;
} }
@Override @Override

View File

@ -12,7 +12,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
@ -35,10 +34,8 @@ import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping.DiscriminatorValueDetails;
import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.TableDetails; import org.hibernate.metamodel.mapping.TableDetails;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.spi.PersisterCreationContext;
@ -49,8 +46,6 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.model.ast.builder.MutationGroupBuilder; import org.hibernate.sql.model.ast.builder.MutationGroupBuilder;
import org.hibernate.sql.model.ast.builder.TableInsertBuilder; import org.hibernate.sql.model.ast.builder.TableInsertBuilder;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import static org.hibernate.internal.util.collections.ArrayHelper.to2DStringArray; import static org.hibernate.internal.util.collections.ArrayHelper.to2DStringArray;
import static org.hibernate.internal.util.collections.ArrayHelper.toBooleanArray; import static org.hibernate.internal.util.collections.ArrayHelper.toBooleanArray;
@ -324,7 +319,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
SqmFunctionRegistry functionRegistry = factory.getQueryEngine().getSqmFunctionRegistry(); SqmFunctionRegistry functionRegistry = factory.getQueryEngine().getSqmFunctionRegistry();
discriminatorType = DiscriminatorHelper.getDiscriminatorType( persistentClass ); discriminatorType = DiscriminatorHelper.getDiscriminatorType( persistentClass );
discriminatorValue = DiscriminatorHelper.getDiscriminatorValue( persistentClass ); discriminatorValue = DiscriminatorHelper.getDiscriminatorValue( persistentClass );
discriminatorSQLValue = DiscriminatorHelper.getDiscriminatorSQLValue( persistentClass, dialect, factory ); discriminatorSQLValue = DiscriminatorHelper.getDiscriminatorSQLValue( persistentClass, dialect );
discriminatorInsertable = isDiscriminatorInsertable( persistentClass ); discriminatorInsertable = isDiscriminatorInsertable( persistentClass );
if ( discriminator.hasFormula() ) { if ( discriminator.hasFormula() ) {
Formula formula = (Formula) selectable; Formula formula = (Formula) selectable;
@ -484,10 +479,15 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
} }
@Override @Override
public Type getDiscriminatorType() { public BasicType<?> getDiscriminatorType() {
return discriminatorType; return discriminatorType;
} }
@Override
public Map<Object, String> getSubclassByDiscriminatorValue() {
return subclassesByDiscriminatorValue;
}
@Override @Override
public TableDetails getMappedTableDetails() { public TableDetails getMappedTableDetails() {
return getTableMapping( 0 ); return getTableMapping( 0 );
@ -668,36 +668,6 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
return getTableSpan() > 1; return getTableSpan() > 1;
} }
@Override
protected Map<Object, DiscriminatorValueDetails> buildDiscriminatorValueMappings(
PersistentClass bootEntityDescriptor,
MappingModelCreationProcess modelCreationProcess) {
final MappingMetamodelImplementor mappingModel = modelCreationProcess.getCreationContext()
.getSessionFactory()
.getMappingMetamodel();
//noinspection unchecked
final JdbcLiteralFormatter<Object> jdbcLiteralFormatter =
(JdbcLiteralFormatter<Object>) discriminatorType.getJdbcLiteralFormatter();
final Dialect dialect = modelCreationProcess.getCreationContext()
.getSessionFactory().getJdbcServices().getDialect();
final Map<Object, DiscriminatorValueDetails> valueMappings = new ConcurrentHashMap<>();
subclassesByDiscriminatorValue.forEach( (value, entityName) -> {
final String jdbcLiteral = value == NULL_DISCRIMINATOR || value == NOT_NULL_DISCRIMINATOR
? null
: jdbcLiteralFormatter.toJdbcLiteral( value, dialect, null );
final DiscriminatorValueDetailsImpl valueMapping = new DiscriminatorValueDetailsImpl(
value,
jdbcLiteral,
mappingModel.findEntityDescriptor( entityName )
);
valueMappings.put( value, valueMapping );
} );
return valueMappings;
}
@Override @Override
public String[] getConstraintOrderedTableNameClosure() { public String[] getConstraintOrderedTableNameClosure() {
return constraintOrderedTableNames; return constraintOrderedTableNames;

View File

@ -17,7 +17,6 @@ import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -63,8 +62,6 @@ import org.hibernate.sql.ast.tree.from.UnionTableReference;
import org.hibernate.sql.ast.tree.predicate.Predicate; import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
/** /**
* An {@link EntityPersister} implementing the * An {@link EntityPersister} implementing the
@ -306,10 +303,15 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
} }
@Override @Override
public Type getDiscriminatorType() { public BasicType<?> getDiscriminatorType() {
return discriminatorType; return discriminatorType;
} }
@Override
public Map<Object, String> getSubclassByDiscriminatorValue() {
return subclassByDiscriminatorValue;
}
@Override @Override
public TableDetails getMappedTableDetails() { public TableDetails getMappedTableDetails() {
return getTableMapping( 0 ); return getTableMapping( 0 );
@ -335,29 +337,6 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
return subclassByDiscriminatorValue.get( value ); return subclassByDiscriminatorValue.get( value );
} }
@Override
protected Map<Object, EntityDiscriminatorMapping.DiscriminatorValueDetails> buildDiscriminatorValueMappings(PersistentClass bootEntityDescriptor, MappingModelCreationProcess modelCreationProcess) {
final MappingMetamodelImplementor mappingModel = modelCreationProcess.getCreationContext()
.getSessionFactory()
.getMappingMetamodel();
//noinspection unchecked
final JdbcLiteralFormatter<Object> jdbcLiteralFormatter = (JdbcLiteralFormatter<Object>) discriminatorType.getJdbcLiteralFormatter();
final Dialect dialect = modelCreationProcess.getCreationContext().getSessionFactory().getJdbcServices().getDialect();
final Map<Object, EntityDiscriminatorMapping.DiscriminatorValueDetails> valueMappings = new ConcurrentHashMap<>();
subclassByDiscriminatorValue.forEach( (value, entityName) -> {
final DiscriminatorValueDetailsImpl valueMapping = new DiscriminatorValueDetailsImpl(
value,
jdbcLiteralFormatter.toJdbcLiteral( value, dialect, null ),
mappingModel.findEntityDescriptor( entityName )
);
valueMappings.put( value, valueMapping );
} );
return valueMappings;
}
@Override @Override
public Serializable[] getPropertySpaces() { public Serializable[] getPropertySpaces() {
return spaces; return spaces;

View File

@ -34,9 +34,7 @@ import org.hibernate.generator.Generator;
import org.hibernate.generator.OnExecutionGenerator; import org.hibernate.generator.OnExecutionGenerator;
import org.hibernate.generator.BeforeExecutionGenerator; import org.hibernate.generator.BeforeExecutionGenerator;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.GeneratorCreator; import org.hibernate.mapping.GeneratorCreator;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
@ -58,6 +56,11 @@ import org.hibernate.type.ManyToOneType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import static org.hibernate.internal.CoreLogging.messageLogger; import static org.hibernate.internal.CoreLogging.messageLogger;
import static org.hibernate.internal.util.ReflectHelper.isAbstractClass;
import static org.hibernate.internal.util.ReflectHelper.isFinalClass;
import static org.hibernate.internal.util.collections.ArrayHelper.toIntArray;
import static org.hibernate.internal.util.collections.CollectionHelper.toSmallMap;
import static org.hibernate.internal.util.collections.CollectionHelper.toSmallSet;
/** /**
* Centralizes metamodel information about an entity. * Centralizes metamodel information about an entity.
@ -365,16 +368,16 @@ public class EntityMetamodel implements Serializable {
mutableIndexes.set( i ); mutableIndexes.set( i );
} }
mapPropertyToIndex(property, i); mapPropertyToIndex( property, i );
} }
if (naturalIdNumbers.size()==0) { if ( naturalIdNumbers.isEmpty() ) {
naturalIdPropertyNumbers = null; naturalIdPropertyNumbers = null;
hasImmutableNaturalId = false; hasImmutableNaturalId = false;
hasCacheableNaturalId = false; hasCacheableNaturalId = false;
} }
else { else {
naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers); naturalIdPropertyNumbers = toIntArray( naturalIdNumbers );
hasImmutableNaturalId = !foundUpdateableNaturalIdProperty; hasImmutableNaturalId = !foundUpdateableNaturalIdProperty;
hasCacheableNaturalId = persistentClass.getNaturalIdCacheRegionName() != null; hasCacheableNaturalId = persistentClass.getNaturalIdCacheRegionName() != null;
} }
@ -392,25 +395,26 @@ public class EntityMetamodel implements Serializable {
versionPropertyIndex = tempVersionProperty; versionPropertyIndex = tempVersionProperty;
hasLazyProperties = hasLazy; hasLazyProperties = hasLazy;
if ( hasLazyProperties ) { if ( hasLazyProperties ) {
LOG.lazyPropertyFetchingAvailable(name); LOG.lazyPropertyFetchingAvailable( name );
} }
lazy = persistentClass.isLazy() && ( lazy = persistentClass.isLazy() && (
// TODO: this disables laziness even in non-pojo entity modes: // TODO: this disables laziness even in non-pojo entity modes:
!persistentClass.hasPojoRepresentation() || !persistentClass.hasPojoRepresentation() ||
!ReflectHelper.isFinalClass( persistentClass.getProxyInterface() ) !isFinalClass( persistentClass.getProxyInterface() )
); );
mutable = persistentClass.isMutable(); mutable = persistentClass.isMutable();
if ( persistentClass.isAbstract() == null ) { if ( persistentClass.isAbstract() == null ) {
// legacy behavior (with no abstract attribute specified) // legacy behavior (with no abstract attribute specified)
isAbstract = persistentClass.hasPojoRepresentation() && isAbstract = persistentClass.hasPojoRepresentation()
ReflectHelper.isAbstractClass( persistentClass.getMappedClass() ); && isAbstractClass( persistentClass.getMappedClass() );
} }
else { else {
isAbstract = persistentClass.isAbstract(); isAbstract = persistentClass.isAbstract();
if ( !isAbstract && persistentClass.hasPojoRepresentation() && if ( !isAbstract
ReflectHelper.isAbstractClass( persistentClass.getMappedClass() ) ) { && persistentClass.hasPojoRepresentation()
LOG.entityMappedAsNonAbstract(name); && isAbstractClass( persistentClass.getMappedClass() ) ) {
LOG.entityMappedAsNonAbstract( name );
} }
} }
@ -447,7 +451,7 @@ public class EntityMetamodel implements Serializable {
subclassEntityNamesLocal.add( subclass.getEntityName() ); subclassEntityNamesLocal.add( subclass.getEntityName() );
} }
subclassEntityNamesLocal.add( name ); subclassEntityNamesLocal.add( name );
subclassEntityNames = CollectionHelper.toSmallSet( subclassEntityNamesLocal ); subclassEntityNames = toSmallSet( subclassEntityNamesLocal );
HashMap<Class<?>, String> entityNameByInheritanceClassMapLocal = new HashMap<>(); HashMap<Class<?>, String> entityNameByInheritanceClassMapLocal = new HashMap<>();
if ( persistentClass.hasPojoRepresentation() ) { if ( persistentClass.hasPojoRepresentation() ) {
@ -456,7 +460,7 @@ public class EntityMetamodel implements Serializable {
entityNameByInheritanceClassMapLocal.put( subclass.getMappedClass(), subclass.getEntityName() ); entityNameByInheritanceClassMapLocal.put( subclass.getMappedClass(), subclass.getEntityName() );
} }
} }
entityNameByInheritanceClassMap = CollectionHelper.toSmallMap( entityNameByInheritanceClassMapLocal ); entityNameByInheritanceClassMap = toSmallMap( entityNameByInheritanceClassMapLocal );
} }
private static boolean generatedWithNoParameter(Generator generator) { private static boolean generatedWithNoParameter(Generator generator) {
@ -738,7 +742,7 @@ public class EntityMetamodel implements Serializable {
@Override @Override
public String toString() { public String toString() {
return "EntityMetamodel(" + name + ':' + ArrayHelper.toString(properties) + ')'; return "EntityMetamodel(" + name + ':' + ArrayHelper.toString( properties ) + ')';
} }
// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -13,6 +13,8 @@ import java.util.List;
import static jakarta.persistence.CascadeType.ALL; import static jakarta.persistence.CascadeType.ALL;
import static jakarta.persistence.InheritanceType.JOINED; import static jakarta.persistence.InheritanceType.JOINED;
import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertNull;
import static junit.framework.TestCase.assertTrue; import static junit.framework.TestCase.assertTrue;
import static org.hibernate.cfg.AvailableSettings.FORMAT_SQL; import static org.hibernate.cfg.AvailableSettings.FORMAT_SQL;
import static org.hibernate.cfg.AvailableSettings.SHOW_SQL; import static org.hibernate.cfg.AvailableSettings.SHOW_SQL;
@ -20,7 +22,7 @@ import static org.hibernate.cfg.AvailableSettings.SHOW_SQL;
public class RepeatedTableTest extends BaseCoreFunctionalTestCase { public class RepeatedTableTest extends BaseCoreFunctionalTestCase {
@Override @Override
protected Class[] getAnnotatedClasses() { protected Class<?>[] getAnnotatedClasses() {
return new Class[]{ return new Class[]{
DataType.class, DataType.class,
ObjectType.class, ObjectType.class,
@ -81,6 +83,9 @@ public class RepeatedTableTest extends BaseCoreFunctionalTestCase {
} }
try (Session sess = openSession()) { try (Session sess = openSession()) {
SimpleType simpleType = sess.find(SimpleType.class, sId); SimpleType simpleType = sess.find(SimpleType.class, sId);
assertNotNull( simpleType );
SimpleType wrongType = sess.find(SimpleType.class, id);
assertNull( wrongType );
} }
try (Session sess = openSession()) { try (Session sess = openSession()) {