improvements to how discriminators are handled by AbstractEntityPersister
This commit is contained in:
parent
b1e2eca53e
commit
e918f92f48
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
)
|
||||||
)
|
);
|
||||||
);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
Loading…
Reference in New Issue