Skip to content

Commit

Permalink
improvements to how discriminators are handled by AbstractEntityPersi…
Browse files Browse the repository at this point in the history
…ster
  • Loading branch information
gavinking committed Dec 26, 2022
1 parent b1e2eca commit e918f92
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 205 deletions.
Expand Up @@ -641,9 +641,11 @@ private void singleTableInheritance(InheritanceState inheritanceState, PropertyH
processDiscriminatorOptions();
final AnnotatedDiscriminatorColumn discriminatorColumn = processSingleTableDiscriminatorProperties( inheritanceState );
if ( !inheritanceState.hasParents() ) { // todo : sucks that this is separate from RootClass distinction
final RootClass rootClass = (RootClass) persistentClass;
if ( inheritanceState.hasSiblings()
|| discriminatorColumn != null && !discriminatorColumn.isImplicit() ) {
bindDiscriminatorColumnToRootPersistentClass( (RootClass) persistentClass, discriminatorColumn, holder );
bindDiscriminatorColumnToRootPersistentClass(rootClass, discriminatorColumn, holder );
rootClass.setForceDiscriminator( isForceDiscriminatorInSelects() );
}
}
}
Expand All @@ -668,13 +670,15 @@ private void joinedInheritance(InheritanceState state, PersistentClass superEnti

final AnnotatedDiscriminatorColumn discriminatorColumn = processJoinedDiscriminatorProperties( state );
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
// let's see if we had a discriminator column (it's perfectly
// valid for joined inheritance to not have a discriminator)
if ( discriminatorColumn != null ) {
// we do have a discriminator column
if ( state.hasSiblings() || !discriminatorColumn.isImplicit() ) {
bindDiscriminatorColumnToRootPersistentClass( (RootClass) persistentClass, discriminatorColumn, holder );
bindDiscriminatorColumnToRootPersistentClass(rootClass, discriminatorColumn, holder );
rootClass.setForceDiscriminator( isForceDiscriminatorInSelects() );
}
}
}
Expand Down Expand Up @@ -750,7 +754,6 @@ private void bindDiscriminatorColumnToRootPersistentClass(
new NullableDiscriminatorColumnSecondPass( rootClass.getEntityName() )
);
}
rootClass.setForceDiscriminator( isForceDiscriminatorInSelects() );
if ( insertableDiscriminator != null ) {
rootClass.setDiscriminatorInsertable( insertableDiscriminator );
}
Expand Down
Expand Up @@ -11,7 +11,6 @@
import org.hibernate.InstantiationException;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
Expand Down
Expand Up @@ -48,29 +48,30 @@ public CaseStatementDiscriminatorMappingImpl(
int[] notNullColumnTableNumbers,
String[] notNullColumnNames,
String[] discriminatorValues,
boolean[] discriminatorAbstract,
Map<String,String> subEntityNameByTableName,
DiscriminatorType<?> incomingDiscriminatorType,
Map<Object, DiscriminatorValueDetails> valueMappings,
MappingModelCreationProcess creationProcess) {
super( entityDescriptor, incomingDiscriminatorType, valueMappings, creationProcess );

for ( int i = 0; i < discriminatorValues.length; i++ ) {
final String tableName = tableNames[notNullColumnTableNumbers[i]];
final String subEntityName = subEntityNameByTableName.get( tableName );
final String oneSubEntityColumn = notNullColumnNames[i];

final String rawDiscriminatorValue = discriminatorValues[i];
final Object discriminatorValue = getUnderlyingJdbcMappingType().getJavaTypeDescriptor().wrap( rawDiscriminatorValue, null );

tableDiscriminatorDetailsMap.put(
tableName,
new TableDiscriminatorDetails(
tableName,
oneSubEntityColumn,
discriminatorValue,
subEntityName
)
);
for ( int i = 0; i < discriminatorValues.length; i++ ) {
if ( !discriminatorAbstract[i] ) {
final String tableName = tableNames[notNullColumnTableNumbers[i]];
final String subEntityName = subEntityNameByTableName.get( tableName );
final String oneSubEntityColumn = notNullColumnNames[i];
final String discriminatorValue = discriminatorValues[i];
tableDiscriminatorDetailsMap.put(
tableName,
new TableDiscriminatorDetails(
tableName,
oneSubEntityColumn,
getUnderlyingJdbcMappingType().getJavaTypeDescriptor()
.wrap( discriminatorValue, null ),
subEntityName
)
);
}
}
}

Expand Down
Expand Up @@ -26,6 +26,7 @@
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
Expand Down Expand Up @@ -111,7 +112,6 @@
import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.FilterHelper;
import org.hibernate.internal.util.LazyValue;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
Expand Down Expand Up @@ -191,6 +191,7 @@
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.spi.EntityInstantiator;
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.mutation.DeleteCoordinator;
Expand All @@ -203,7 +204,6 @@
import org.hibernate.persister.internal.ImmutableAttributeMappingList;
import org.hibernate.persister.internal.SqlFragmentPredicate;
import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.Setter;
import org.hibernate.query.SemanticException;
Expand Down Expand Up @@ -275,6 +275,7 @@
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;

import static java.util.Collections.emptySet;
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
Expand All @@ -284,6 +285,7 @@
import static org.hibernate.engine.internal.Versioning.isVersionIncrementRequired;
import static org.hibernate.generator.EventType.INSERT;
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.collections.ArrayHelper.contains;
import static org.hibernate.internal.util.collections.ArrayHelper.to2DStringArray;
Expand All @@ -297,6 +299,7 @@
import static org.hibernate.metamodel.RepresentationMode.POJO;
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.discriminatorLiteral;
import static org.hibernate.pretty.MessageHelper.infoString;
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;

Expand Down Expand Up @@ -452,7 +455,7 @@ public abstract class AbstractEntityPersister

protected ReflectionOptimizer.AccessOptimizer accessOptimizer;

private final String[] fullDiscriminatorSQLValues;
// private final String[] fullDiscriminatorSQLValues;
private final Object[] fullDiscriminatorValues;

/**
Expand Down Expand Up @@ -800,36 +803,36 @@ else if ( batchSize > 1 ) {
&& shouldInvalidateCache( bootDescriptor, creationContext );

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 ( !getEntityMetamodel().isAbstract() ) {
Object discriminatorValue = DiscriminatorHelper.getDiscriminatorValue( bootDescriptor );
String discriminatorSQLValue = DiscriminatorHelper.getDiscriminatorSQLValue( bootDescriptor, dialect, factory );
values.add( discriminatorValue );
sqlValues.add( discriminatorSQLValue );
values.add( DiscriminatorHelper.getDiscriminatorValue( bootDescriptor ) );
// sqlValues.add( DiscriminatorHelper.getDiscriminatorSQLValue( bootDescriptor, dialect, factory ) );
}

final List<Subclass> subclasses = bootDescriptor.getSubclasses();
for ( int k = 0; k < subclasses.size(); k++ ) {
Subclass subclass = subclasses.get( k );
final Subclass subclass = subclasses.get( k );
//copy/paste from EntityMetamodel:
boolean subclassAbstract = subclass.isAbstract() == null
? subclass.hasPojoRepresentation() && ReflectHelper.isAbstractClass( subclass.getMappedClass() )
: subclass.isAbstract();

if ( !subclassAbstract ) {
Object subclassDiscriminatorValue = DiscriminatorHelper.getDiscriminatorValue( subclass );
values.add( subclassDiscriminatorValue );
sqlValues.add( DiscriminatorHelper.getDiscriminatorSQLValue( subclass, dialect, factory ) );
if ( !isAbstract( subclass ) ) {
values.add( DiscriminatorHelper.getDiscriminatorValue( subclass ) );
// sqlValues.add( DiscriminatorHelper.getDiscriminatorSQLValue( subclass, dialect, factory ) );
}
}
}

fullDiscriminatorSQLValues = toStringArray( sqlValues );
// fullDiscriminatorSQLValues = toStringArray( sqlValues );
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() {
// Check if we can use Reference Cached entities in 2lc
// todo : should really validate that the cache access type is read-only
Expand Down Expand Up @@ -2225,12 +2228,9 @@ public String[] toColumns(String name, final int i) {
String[] templates = getSubclassPropertyFormulaTemplateClosure()[i];
String[] result = new String[cols.length];
for ( int j = 0; j < cols.length; j++ ) {
if ( cols[j] == null ) {
result[j] = StringHelper.replace( templates[j], Template.TEMPLATE, alias );
}
else {
result[j] = StringHelper.qualify( alias, cols[j] );
}
result[j] = cols[j] == null
? StringHelper.replace( templates[j], Template.TEMPLATE, alias )
: StringHelper.qualify( alias, cols[j] );
}
return result;
}
Expand Down Expand Up @@ -2927,6 +2927,8 @@ protected void logStaticSQL() {
}
}

public abstract Map<Object, String> getSubclassByDiscriminatorValue();

protected abstract boolean needsDiscriminator();

protected boolean isDiscriminatorFormula() {
Expand Down Expand Up @@ -4929,7 +4931,7 @@ private void prepareMappingModel(MappingModelCreationProcess creationProcess, Pe
else {
rowIdMapping = creationProcess.processSubPart(
rowIdName,
(role, process) -> new EntityRowIdMappingImpl( rowIdName, this.getTableName(), this )
(role, process) -> new EntityRowIdMappingImpl( rowIdName, getTableName(), this )
);
}

Expand Down Expand Up @@ -5064,7 +5066,7 @@ protected boolean isPhysicalDiscriminator() {
protected EntityDiscriminatorMapping generateDiscriminatorMapping(
PersistentClass bootEntityDescriptor,
MappingModelCreationProcess modelCreationProcess) {
if ( getDiscriminatorType() == null) {
if ( getDiscriminatorType() == null ) {
return null;
}
else {
Expand All @@ -5074,7 +5076,7 @@ protected EntityDiscriminatorMapping generateDiscriminatorMapping(
final Integer precision;
final Integer scale;
if ( getDiscriminatorFormulaTemplate() == null ) {
Column column = bootEntityDescriptor.getDiscriminator() == null
final Column column = bootEntityDescriptor.getDiscriminator() == null
? null
: bootEntityDescriptor.getDiscriminator().getColumns().get( 0 );
discriminatorColumnExpression = getDiscriminatorColumnReaders();
Expand All @@ -5098,24 +5100,46 @@ protected EntityDiscriminatorMapping generateDiscriminatorMapping(
precision = null;
scale = null;
}
return new ExplicitColumnDiscriminatorMappingImpl (
return new ExplicitColumnDiscriminatorMappingImpl(
this,
getTableName(),
discriminatorColumnExpression,
getDiscriminatorFormulaTemplate() != null,
isPhysicalDiscriminator(),
columnDefinition, length, precision, scale,
(DiscriminatorType<?>) getTypeDiscriminatorMetadata().getResolutionType(),
buildDiscriminatorValueMappings( bootEntityDescriptor, modelCreationProcess ),
buildDiscriminatorValueMappings( modelCreationProcess ),
modelCreationProcess
);
}
}

protected abstract Map<Object, DiscriminatorValueDetails> buildDiscriminatorValueMappings(
PersistentClass bootEntityDescriptor,
MappingModelCreationProcess modelCreationProcess);
@Override
public abstract BasicType<?> getDiscriminatorType();

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(
Supplier<?> templateInstanceCreator,
Expand Down
Expand Up @@ -38,22 +38,15 @@ static BasicType<?> getDiscriminatorType(PersistentClass persistentClass) {
}
}

static String getDiscriminatorSQLValue(
PersistentClass persistentClass,
Dialect dialect,
SessionFactoryImplementor factory) {
static String getDiscriminatorSQLValue(PersistentClass persistentClass, Dialect dialect) {
if ( persistentClass.isDiscriminatorValueNull() ) {
return InFragment.NULL;
}
else if ( persistentClass.isDiscriminatorValueNotNull() ) {
return InFragment.NOT_NULL;
}
else {
return discriminatorSqlLiteral(
getDiscriminatorType( persistentClass ),
persistentClass,
dialect
);
return discriminatorSqlLiteral( getDiscriminatorType( persistentClass ), persistentClass, dialect );
}
}

Expand All @@ -62,7 +55,7 @@ private static Object parseDiscriminatorValue(PersistentClass persistentClass) {
try {
return discriminatorType.getJavaTypeDescriptor().fromString( persistentClass.getDiscriminatorValue() );
}
catch (Exception e) {
catch ( Exception e ) {
throw new MappingException( "Could not parse discriminator value", e );
}
}
Expand Down Expand Up @@ -90,7 +83,7 @@ private static <T> String discriminatorSqlLiteral(
);
}

public static <T> String jdbcLiteral(
private static <T> String jdbcLiteral(
T value,
JdbcLiteralFormatter<T> formatter,
Dialect dialect) {
Expand All @@ -101,4 +94,11 @@ public static <T> String jdbcLiteral(
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 );
}

}

0 comments on commit e918f92

Please sign in to comment.