HHH-18733 - Add a prepareMappingModel phase to collection persisters
Co-authored-by: Christian Beikov <christian.beikov@gmail.com>
This commit is contained in:
parent
84cc5f013c
commit
d647599fe9
|
@ -12,6 +12,7 @@ import java.util.function.Consumer;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
|
import org.hibernate.type.AnyDiscriminatorValueStrategy;
|
||||||
import org.hibernate.type.AnyType;
|
import org.hibernate.type.AnyType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.MappingContext;
|
import org.hibernate.type.MappingContext;
|
||||||
|
@ -301,9 +302,13 @@ public class Any extends SimpleValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The discriminator {@linkplain Value}
|
||||||
|
*/
|
||||||
public static class MetaValue extends SimpleValue {
|
public static class MetaValue extends SimpleValue {
|
||||||
private String typeName;
|
private String typeName;
|
||||||
private String columnName;
|
private String columnName;
|
||||||
|
private AnyDiscriminatorValueStrategy valueStrategy;
|
||||||
|
|
||||||
private final Consumer<Selectable> selectableConsumer;
|
private final Consumer<Selectable> selectableConsumer;
|
||||||
|
|
||||||
|
@ -396,6 +401,10 @@ public class Any extends SimpleValue {
|
||||||
return columnName != null
|
return columnName != null
|
||||||
&& getType().getColumnSpan( mappingContext ) == 1;
|
&& getType().getColumnSpan( mappingContext ) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AnyDiscriminatorValueStrategy getValueStrategy() {
|
||||||
|
return valueStrategy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class KeyValue extends SimpleValue {
|
public static class KeyValue extends SimpleValue {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
|
||||||
import org.hibernate.resource.beans.spi.ManagedBean;
|
import org.hibernate.resource.beans.spi.ManagedBean;
|
||||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||||
import org.hibernate.resource.beans.spi.ProvidedInstanceManagedBeanImpl;
|
import org.hibernate.resource.beans.spi.ProvidedInstanceManagedBeanImpl;
|
||||||
|
import org.hibernate.type.AnyDiscriminatorValueStrategy;
|
||||||
import org.hibernate.type.AnyType;
|
import org.hibernate.type.AnyType;
|
||||||
import org.hibernate.type.CollectionType;
|
import org.hibernate.type.CollectionType;
|
||||||
import org.hibernate.type.CustomCollectionType;
|
import org.hibernate.type.CustomCollectionType;
|
||||||
|
@ -123,15 +124,22 @@ public final class MappingHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AnyType anyMapping(
|
public static AnyType anyMapping(
|
||||||
Type metaType,
|
Type discriminatorType,
|
||||||
Type identifierType,
|
Type identifierType,
|
||||||
Map<Object, String> metaValueToEntityNameMap,
|
Map<Object, String> explicitValeMappings,
|
||||||
boolean lazy,
|
boolean lazy,
|
||||||
MetadataBuildingContext buildingContext) {
|
MetadataBuildingContext buildingContext) {
|
||||||
if ( metaValueToEntityNameMap != null ) {
|
return anyMapping( discriminatorType, identifierType, AnyDiscriminatorValueStrategy.AUTO, explicitValeMappings, lazy, buildingContext );
|
||||||
metaType = new MetaType( metaValueToEntityNameMap, metaType );
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
public static AnyType anyMapping(
|
||||||
|
Type discriminatorType,
|
||||||
|
Type identifierType,
|
||||||
|
AnyDiscriminatorValueStrategy discriminatorValueStrategy,
|
||||||
|
Map<Object, String> explicitValeMappings,
|
||||||
|
boolean lazy,
|
||||||
|
MetadataBuildingContext buildingContext) {
|
||||||
|
final MetaType metaType = new MetaType( discriminatorType, discriminatorValueStrategy, explicitValeMappings );
|
||||||
return new AnyType( buildingContext.getBootstrapContext().getTypeConfiguration(), metaType, identifierType, lazy );
|
return new AnyType( buildingContext.getBootstrapContext().getTypeConfiguration(), metaType, identifierType, lazy );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
* Copyright Red Hat Inc. and Hibernate Authors
|
|
||||||
*/
|
|
||||||
package org.hibernate.metamodel.mapping;
|
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.metamodel.mapping.internal.DiscriminatorValueDetailsImpl;
|
|
||||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
|
||||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
|
||||||
import org.hibernate.type.BasicType;
|
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the default discriminator assignment strategy defined by JPA,
|
|
||||||
* that is, the discriminator value is the JPA (unqualified) entity name.
|
|
||||||
* This strategy is used when no explicit discriminator mapping is specified.
|
|
||||||
*
|
|
||||||
* @author Gavin King
|
|
||||||
*/
|
|
||||||
public class DefaultDiscriminatorConverter<O,R> extends DiscriminatorConverter<O,R> {
|
|
||||||
|
|
||||||
public static <O,R> DefaultDiscriminatorConverter<O,R> fromMappingMetamodel(
|
|
||||||
NavigableRole role,
|
|
||||||
JavaType<O> domainJavaType,
|
|
||||||
BasicType<R> underlyingJdbcMapping,
|
|
||||||
MappingMetamodelImplementor mappingMetamodel) {
|
|
||||||
return new DefaultDiscriminatorConverter<>(
|
|
||||||
role,
|
|
||||||
domainJavaType,
|
|
||||||
underlyingJdbcMapping.getJavaTypeDescriptor(),
|
|
||||||
mappingMetamodel
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final MappingMetamodelImplementor mappingMetamodel;
|
|
||||||
|
|
||||||
public DefaultDiscriminatorConverter(
|
|
||||||
NavigableRole discriminatorRole,
|
|
||||||
JavaType<O> domainJavaType,
|
|
||||||
JavaType<R> relationalJavaType,
|
|
||||||
MappingMetamodelImplementor mappingMetamodel) {
|
|
||||||
super( discriminatorRole.getFullPath(), domainJavaType, relationalJavaType );
|
|
||||||
this.mappingMetamodel = mappingMetamodel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DiscriminatorValueDetails getDetailsForRelationalForm(R relationalForm) {
|
|
||||||
return getDetailsForDiscriminatorValue( relationalForm );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DiscriminatorValueDetails getDetailsForEntityName(String entityName) {
|
|
||||||
EntityPersister persister = mappingMetamodel.findEntityDescriptor( entityName );
|
|
||||||
if ( persister!= null ) {
|
|
||||||
return new DiscriminatorValueDetailsImpl( entityName, persister );
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new AssertionFailure( "Unrecognized entity name: " + entityName );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DiscriminatorValueDetails getDetailsForDiscriminatorValue(Object value) {
|
|
||||||
if ( value instanceof String ) {
|
|
||||||
String entityName = mappingMetamodel.getImportedName( (String) value );
|
|
||||||
EntityPersister persister = mappingMetamodel.findEntityDescriptor( entityName );
|
|
||||||
if ( persister!= null ) {
|
|
||||||
return new DiscriminatorValueDetailsImpl( entityName, persister );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new HibernateException( "Unrecognized discriminator value: " + value );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void forEachValueDetail(Consumer<DiscriminatorValueDetails> consumer) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <X> X fromValueDetails(Function<DiscriminatorValueDetails,X> handler) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,151 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
* Copyright Red Hat Inc. and Hibernate Authors
|
|
||||||
*/
|
|
||||||
package org.hibernate.metamodel.mapping;
|
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
|
||||||
import org.hibernate.metamodel.mapping.internal.DiscriminatorValueDetailsImpl;
|
|
||||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
|
||||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
|
||||||
import org.hibernate.type.BasicType;
|
|
||||||
import org.hibernate.type.descriptor.java.CharacterJavaType;
|
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
|
||||||
import org.hibernate.type.descriptor.java.StringJavaType;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR;
|
|
||||||
import static org.hibernate.persister.entity.DiscriminatorHelper.NULL_DISCRIMINATOR;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Conversion of discriminator values between the entity name/Class domain form and
|
|
||||||
* its generally CHARACTER or INTEGER based relational form
|
|
||||||
*
|
|
||||||
* @param <O> The domain type - either <ul>
|
|
||||||
* <li>
|
|
||||||
* the {@linkplain EntityMappingType#getMappedJavaType() entity Class} for unnamed entities
|
|
||||||
* </li>
|
|
||||||
* <li>
|
|
||||||
* the {@linkplain EntityMappingType#getEntityName() entity name} for named entities
|
|
||||||
* </li>
|
|
||||||
* </ul>
|
|
||||||
* @param <R> The Java type of the relational form of the discriminator
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class MappedDiscriminatorConverter<O,R> extends DiscriminatorConverter<O,R> {
|
|
||||||
|
|
||||||
public static <O,R> MappedDiscriminatorConverter<O,R> fromValueMappings(
|
|
||||||
NavigableRole role,
|
|
||||||
JavaType<O> domainJavaType,
|
|
||||||
BasicType<R> underlyingJdbcMapping,
|
|
||||||
Map<Object,String> valueMappings,
|
|
||||||
MappingMetamodelImplementor mappingMetamodel) {
|
|
||||||
final List<DiscriminatorValueDetails> valueDetailsList = CollectionHelper.arrayList( valueMappings.size() );
|
|
||||||
valueMappings.forEach( (value, entityName) -> {
|
|
||||||
final DiscriminatorValueDetails valueDetails = new DiscriminatorValueDetailsImpl(
|
|
||||||
value,
|
|
||||||
mappingMetamodel.getEntityDescriptor( entityName )
|
|
||||||
);
|
|
||||||
valueDetailsList.add( valueDetails );
|
|
||||||
} );
|
|
||||||
|
|
||||||
return new MappedDiscriminatorConverter<>(
|
|
||||||
role,
|
|
||||||
domainJavaType,
|
|
||||||
underlyingJdbcMapping.getJavaTypeDescriptor(),
|
|
||||||
valueDetailsList
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Map<Object, DiscriminatorValueDetails> discriminatorValueToEntityNameMap;
|
|
||||||
private final Map<String,DiscriminatorValueDetails> entityNameToDiscriminatorValueMap;
|
|
||||||
|
|
||||||
public MappedDiscriminatorConverter(
|
|
||||||
NavigableRole discriminatorRole,
|
|
||||||
JavaType<O> domainJavaType,
|
|
||||||
JavaType<R> relationalJavaType,
|
|
||||||
List<DiscriminatorValueDetails> valueMappings) {
|
|
||||||
super( discriminatorRole.getFullPath(), domainJavaType, relationalJavaType );
|
|
||||||
|
|
||||||
this.discriminatorValueToEntityNameMap = CollectionHelper.concurrentMap( valueMappings.size() );
|
|
||||||
this.entityNameToDiscriminatorValueMap = CollectionHelper.concurrentMap( valueMappings.size() );
|
|
||||||
valueMappings.forEach( (valueDetails) -> {
|
|
||||||
discriminatorValueToEntityNameMap.put( valueDetails.getValue(), valueDetails );
|
|
||||||
entityNameToDiscriminatorValueMap.put( valueDetails.getIndicatedEntityName(), valueDetails );
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DiscriminatorValueDetails getDetailsForRelationalForm(R relationalForm) {
|
|
||||||
return getDetailsForDiscriminatorValue( relationalForm );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DiscriminatorValueDetails getDetailsForEntityName(String entityName) {
|
|
||||||
DiscriminatorValueDetails valueDetails = entityNameToDiscriminatorValueMap.get( entityName );
|
|
||||||
if ( valueDetails!= null) {
|
|
||||||
return valueDetails;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new AssertionFailure( "Unrecognized entity name: " + entityName );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DiscriminatorValueDetails getDetailsForDiscriminatorValue(Object value) {
|
|
||||||
if ( value == null ) {
|
|
||||||
return discriminatorValueToEntityNameMap.get( NULL_DISCRIMINATOR );
|
|
||||||
}
|
|
||||||
|
|
||||||
final DiscriminatorValueDetails valueMatch = discriminatorValueToEntityNameMap.get( value );
|
|
||||||
if ( valueMatch != null ) {
|
|
||||||
return valueMatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
final DiscriminatorValueDetails notNullMatch = discriminatorValueToEntityNameMap.get( NOT_NULL_DISCRIMINATOR );
|
|
||||||
if ( notNullMatch != null ) {
|
|
||||||
return notNullMatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( value.getClass().isEnum() ) {
|
|
||||||
final Object enumValue;
|
|
||||||
if ( getRelationalJavaType() instanceof StringJavaType ) {
|
|
||||||
enumValue = ( (Enum) value ).name();
|
|
||||||
}
|
|
||||||
else if ( getRelationalJavaType() instanceof CharacterJavaType ) {
|
|
||||||
enumValue = ( (Enum) value ).name().charAt( 0 );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
enumValue = ( (Enum) value ).ordinal();
|
|
||||||
}
|
|
||||||
final DiscriminatorValueDetails enumMatch = discriminatorValueToEntityNameMap.get( enumValue );
|
|
||||||
if ( enumMatch != null ) {
|
|
||||||
return enumMatch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new HibernateException( "Unrecognized discriminator value: " + value );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void forEachValueDetail(Consumer<DiscriminatorValueDetails> consumer) {
|
|
||||||
discriminatorValueToEntityNameMap.forEach( (value, detail) -> consumer.accept( detail ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <X> X fromValueDetails(Function<DiscriminatorValueDetails,X> handler) {
|
|
||||||
for ( DiscriminatorValueDetails detail : discriminatorValueToEntityNameMap.values() ) {
|
|
||||||
final X result = handler.apply( detail );
|
|
||||||
if ( result != null ) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,23 +4,19 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.mapping.internal;
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
import java.util.Map;
|
import org.hibernate.AssertionFailure;
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
|
|
||||||
import org.hibernate.cache.MutableCacheKeyBuilder;
|
import org.hibernate.cache.MutableCacheKeyBuilder;
|
||||||
import org.hibernate.engine.FetchStyle;
|
import org.hibernate.engine.FetchStyle;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.internal.util.IndexedConsumer;
|
import org.hibernate.internal.util.IndexedConsumer;
|
||||||
import org.hibernate.metamodel.mapping.DefaultDiscriminatorConverter;
|
|
||||||
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
|
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
|
||||||
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
|
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
|
||||||
import org.hibernate.metamodel.mapping.DiscriminatorMapping;
|
import org.hibernate.metamodel.mapping.DiscriminatorMapping;
|
||||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.mapping.MappedDiscriminatorConverter;
|
|
||||||
import org.hibernate.metamodel.mapping.MappingType;
|
import org.hibernate.metamodel.mapping.MappingType;
|
||||||
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
||||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
|
@ -39,10 +35,14 @@ import org.hibernate.sql.results.graph.FetchOptions;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
import org.hibernate.sql.results.graph.basic.BasicFetch;
|
import org.hibernate.sql.results.graph.basic.BasicFetch;
|
||||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||||
|
import org.hibernate.type.AnyDiscriminatorValueStrategy;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.descriptor.java.ClassJavaType;
|
import org.hibernate.type.descriptor.java.ClassJavaType;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Acts as a ModelPart for the discriminator portion of an any-valued mapping
|
* Acts as a ModelPart for the discriminator portion of an any-valued mapping
|
||||||
*
|
*
|
||||||
|
@ -84,6 +84,7 @@ public class AnyDiscriminatorPart implements DiscriminatorMapping, FetchOptions
|
||||||
boolean partitioned,
|
boolean partitioned,
|
||||||
BasicType<?> underlyingJdbcMapping,
|
BasicType<?> underlyingJdbcMapping,
|
||||||
Map<Object,String> valueToEntityNameMap,
|
Map<Object,String> valueToEntityNameMap,
|
||||||
|
AnyDiscriminatorValueStrategy valueStrategy,
|
||||||
MappingMetamodelImplementor mappingMetamodel) {
|
MappingMetamodelImplementor mappingMetamodel) {
|
||||||
this.navigableRole = partRole;
|
this.navigableRole = partRole;
|
||||||
this.declaringType = declaringType;
|
this.declaringType = declaringType;
|
||||||
|
@ -100,20 +101,54 @@ public class AnyDiscriminatorPart implements DiscriminatorMapping, FetchOptions
|
||||||
this.partitioned = partitioned;
|
this.partitioned = partitioned;
|
||||||
|
|
||||||
this.underlyingJdbcMapping = underlyingJdbcMapping;
|
this.underlyingJdbcMapping = underlyingJdbcMapping;
|
||||||
this.valueConverter = valueToEntityNameMap.isEmpty()
|
this.valueConverter = determineDiscriminatorConverter(
|
||||||
? DefaultDiscriminatorConverter.fromMappingMetamodel(
|
partRole,
|
||||||
partRole,
|
underlyingJdbcMapping,
|
||||||
ClassJavaType.INSTANCE,
|
valueToEntityNameMap,
|
||||||
underlyingJdbcMapping,
|
valueStrategy,
|
||||||
mappingMetamodel
|
mappingMetamodel
|
||||||
)
|
);
|
||||||
: MappedDiscriminatorConverter.fromValueMappings(
|
}
|
||||||
partRole,
|
|
||||||
ClassJavaType.INSTANCE,
|
public static DiscriminatorConverter<?, ?> determineDiscriminatorConverter(
|
||||||
underlyingJdbcMapping,
|
NavigableRole partRole,
|
||||||
valueToEntityNameMap,
|
BasicType<?> underlyingJdbcMapping,
|
||||||
mappingMetamodel
|
Map<Object, String> valueToEntityNameMap,
|
||||||
);
|
AnyDiscriminatorValueStrategy valueStrategy,
|
||||||
|
MappingMetamodelImplementor mappingMetamodel) {
|
||||||
|
if ( valueStrategy == AnyDiscriminatorValueStrategy.AUTO ) {
|
||||||
|
if ( valueToEntityNameMap == null || valueToEntityNameMap.isEmpty() ) {
|
||||||
|
valueStrategy = AnyDiscriminatorValueStrategy.IMPLICIT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
valueStrategy = AnyDiscriminatorValueStrategy.EXPLICIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return switch ( valueStrategy ) {
|
||||||
|
case AUTO -> throw new AssertionFailure( "Not expecting AUTO" );
|
||||||
|
case MIXED -> new MixedDiscriminatorConverter<>(
|
||||||
|
partRole,
|
||||||
|
ClassJavaType.INSTANCE,
|
||||||
|
underlyingJdbcMapping.getJavaTypeDescriptor(),
|
||||||
|
valueToEntityNameMap,
|
||||||
|
mappingMetamodel
|
||||||
|
);
|
||||||
|
case EXPLICIT -> new ExplicitDiscriminatorConverter<>(
|
||||||
|
partRole,
|
||||||
|
ClassJavaType.INSTANCE,
|
||||||
|
underlyingJdbcMapping.getJavaTypeDescriptor(),
|
||||||
|
valueToEntityNameMap,
|
||||||
|
mappingMetamodel
|
||||||
|
);
|
||||||
|
case IMPLICIT -> new ImplicitDiscriminatorConverter<>(
|
||||||
|
partRole,
|
||||||
|
ClassJavaType.INSTANCE,
|
||||||
|
underlyingJdbcMapping.getJavaTypeDescriptor(),
|
||||||
|
valueToEntityNameMap,
|
||||||
|
mappingMetamodel
|
||||||
|
);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiscriminatorConverter<?,?> getValueConverter() {
|
public DiscriminatorConverter<?,?> getValueConverter() {
|
||||||
|
|
|
@ -89,6 +89,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
|
||||||
bootValueMapping.isPartitionKey(),
|
bootValueMapping.isPartitionKey(),
|
||||||
(BasicType<?>) metaType.getBaseType(),
|
(BasicType<?>) metaType.getBaseType(),
|
||||||
metaType.getDiscriminatorValuesToEntityNameMap(),
|
metaType.getDiscriminatorValuesToEntityNameMap(),
|
||||||
|
metaType.getValueStrategy(),
|
||||||
creationProcess.getCreationContext().getSessionFactory().getMappingMetamodel()
|
creationProcess.getCreationContext().getSessionFactory().getMappingMetamodel()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
|
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
|
||||||
|
import org.hibernate.metamodel.mapping.DiscriminatorValueDetails;
|
||||||
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
|
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.type.descriptor.java.CharacterJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.StringJavaType;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static java.util.Locale.ROOT;
|
||||||
|
import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR;
|
||||||
|
import static org.hibernate.persister.entity.DiscriminatorHelper.NULL_DISCRIMINATOR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class ExplicitDiscriminatorConverter<O,R> extends DiscriminatorConverter<O, R> {
|
||||||
|
private final NavigableRole discriminatorRole;
|
||||||
|
private final Map<Object, DiscriminatorValueDetails> detailsByValue;
|
||||||
|
private final Map<String,DiscriminatorValueDetails> detailsByEntityName;
|
||||||
|
|
||||||
|
public ExplicitDiscriminatorConverter(
|
||||||
|
NavigableRole discriminatorRole,
|
||||||
|
JavaType<O> domainJavaType,
|
||||||
|
JavaType<R> relationalJavaType,
|
||||||
|
Map<Object, String> explicitValueMappings,
|
||||||
|
MappingMetamodelImplementor mappingMetamodel) {
|
||||||
|
super( discriminatorRole.getFullPath(), domainJavaType, relationalJavaType );
|
||||||
|
this.discriminatorRole = discriminatorRole;
|
||||||
|
|
||||||
|
if ( CollectionHelper.isEmpty( explicitValueMappings ) ) {
|
||||||
|
throw new MappingException( String.format(
|
||||||
|
ROOT,
|
||||||
|
"No explicit ANY discriminator mappings (%s)",
|
||||||
|
discriminatorRole.getFullPath()
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.detailsByValue = CollectionHelper.concurrentMap( explicitValueMappings.size() );
|
||||||
|
this.detailsByEntityName = CollectionHelper.concurrentMap( explicitValueMappings.size() );
|
||||||
|
|
||||||
|
explicitValueMappings.forEach( (value, entityName) -> {
|
||||||
|
final EntityPersister entityDescriptor = mappingMetamodel.getEntityDescriptor( entityName );
|
||||||
|
final DiscriminatorValueDetails details = new DiscriminatorValueDetailsImpl( value, entityDescriptor );
|
||||||
|
detailsByValue.put( value, details );
|
||||||
|
detailsByEntityName.put( entityDescriptor.getEntityName(), details );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DiscriminatorValueDetails getDetailsForDiscriminatorValue(Object relationalForm) {
|
||||||
|
if ( relationalForm == null ) {
|
||||||
|
return detailsByValue.get( NULL_DISCRIMINATOR );
|
||||||
|
}
|
||||||
|
|
||||||
|
final DiscriminatorValueDetails existing = detailsByValue.get( relationalForm );
|
||||||
|
if ( existing != null ) {
|
||||||
|
// an explicit or previously-resolved mapping
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
|
||||||
|
final DiscriminatorValueDetails notNullMatch = detailsByValue.get( NOT_NULL_DISCRIMINATOR );
|
||||||
|
if ( notNullMatch != null ) {
|
||||||
|
return notNullMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( relationalForm.getClass().isEnum() ) {
|
||||||
|
final Object enumValue;
|
||||||
|
if ( getRelationalJavaType() instanceof StringJavaType ) {
|
||||||
|
enumValue = ( (Enum) relationalForm ).name();
|
||||||
|
}
|
||||||
|
else if ( getRelationalJavaType() instanceof CharacterJavaType ) {
|
||||||
|
enumValue = ( (Enum) relationalForm ).name().charAt( 0 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enumValue = ( (Enum) relationalForm ).ordinal();
|
||||||
|
}
|
||||||
|
final DiscriminatorValueDetails enumMatch = detailsByValue.get( enumValue );
|
||||||
|
if ( enumMatch != null ) {
|
||||||
|
return enumMatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new HibernateException( String.format(
|
||||||
|
ROOT,
|
||||||
|
"Unknown discriminator value (%s) : %s",
|
||||||
|
discriminatorRole,
|
||||||
|
relationalForm
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DiscriminatorValueDetails getDetailsForEntityName(String entityName) {
|
||||||
|
final DiscriminatorValueDetails valueDetails = detailsByEntityName.get( entityName );
|
||||||
|
if ( valueDetails != null) {
|
||||||
|
return valueDetails;
|
||||||
|
}
|
||||||
|
throw new HibernateException( "Unknown entity name (" + discriminatorRole + ") : " + entityName );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEachValueDetail(Consumer<DiscriminatorValueDetails> consumer) {
|
||||||
|
detailsByEntityName.forEach( (value, detail) -> consumer.accept( detail ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> X fromValueDetails(Function<DiscriminatorValueDetails, X> handler) {
|
||||||
|
for ( DiscriminatorValueDetails detail : detailsByEntityName.values() ) {
|
||||||
|
final X result = handler.apply( detail );
|
||||||
|
if ( result != null ) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
|
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
|
||||||
|
import org.hibernate.metamodel.mapping.DiscriminatorValueDetails;
|
||||||
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
|
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static java.util.Locale.ROOT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class ImplicitDiscriminatorConverter<O,R> extends DiscriminatorConverter<O,R> {
|
||||||
|
private final NavigableRole discriminatorRole;
|
||||||
|
private final MappingMetamodelImplementor mappingMetamodel;
|
||||||
|
private final Map<Object, DiscriminatorValueDetails> detailsByValue;
|
||||||
|
private final Map<String,DiscriminatorValueDetails> detailsByEntityName;
|
||||||
|
|
||||||
|
public ImplicitDiscriminatorConverter(
|
||||||
|
NavigableRole discriminatorRole,
|
||||||
|
JavaType<O> domainJavaType,
|
||||||
|
JavaType<R> relationalJavaType,
|
||||||
|
Map<Object,String> explicitValueMappings,
|
||||||
|
MappingMetamodelImplementor mappingMetamodel) {
|
||||||
|
super( discriminatorRole.getFullPath(), domainJavaType, relationalJavaType );
|
||||||
|
this.discriminatorRole = discriminatorRole;
|
||||||
|
this.mappingMetamodel = mappingMetamodel;
|
||||||
|
|
||||||
|
if ( CollectionHelper.isNotEmpty( explicitValueMappings ) ) {
|
||||||
|
throw new MappingException( String.format(
|
||||||
|
ROOT,
|
||||||
|
"Encountered explicit ANY discriminator mappings (%s)",
|
||||||
|
discriminatorRole.getFullPath()
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.detailsByValue = CollectionHelper.concurrentMap( 8 );
|
||||||
|
this.detailsByEntityName = CollectionHelper.concurrentMap( 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DiscriminatorValueDetails getDetailsForDiscriminatorValue(Object value) {
|
||||||
|
if ( value instanceof String incoming ) {
|
||||||
|
final DiscriminatorValueDetails existingDetails = detailsByValue.get( incoming );
|
||||||
|
if ( existingDetails != null ) {
|
||||||
|
return existingDetails;
|
||||||
|
}
|
||||||
|
final String entityName = mappingMetamodel.getImportedName( incoming );
|
||||||
|
final EntityPersister persister = mappingMetamodel.findEntityDescriptor( entityName );
|
||||||
|
if ( persister != null ) {
|
||||||
|
assert persister.getImportedName().equals( incoming );
|
||||||
|
return register( incoming, persister );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new HibernateException( String.format(
|
||||||
|
ROOT,
|
||||||
|
"Unrecognized discriminator value (%s): %s",
|
||||||
|
discriminatorRole.getFullPath(),
|
||||||
|
value
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiscriminatorValueDetails register(Object value, EntityPersister entityDescriptor) {
|
||||||
|
final DiscriminatorValueDetails details = new DiscriminatorValueDetailsImpl( value, entityDescriptor );
|
||||||
|
detailsByValue.put( value, details );
|
||||||
|
detailsByEntityName.put( entityDescriptor.getImportedName(), details );
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DiscriminatorValueDetails getDetailsForEntityName(String entityName) {
|
||||||
|
final DiscriminatorValueDetails existingDetails = detailsByEntityName.get( entityName );
|
||||||
|
if ( existingDetails != null ) {
|
||||||
|
return existingDetails;
|
||||||
|
}
|
||||||
|
final EntityPersister persister = mappingMetamodel.findEntityDescriptor( entityName );
|
||||||
|
if ( persister!= null ) {
|
||||||
|
return register( persister.getImportedName(), persister );
|
||||||
|
}
|
||||||
|
throw new HibernateException( String.format(
|
||||||
|
ROOT,
|
||||||
|
"Unrecognized entity name (%s): %s",
|
||||||
|
discriminatorRole.getFullPath(),
|
||||||
|
entityName
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEachValueDetail(Consumer<DiscriminatorValueDetails> consumer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> X fromValueDetails(Function<DiscriminatorValueDetails,X> handler) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the ability to perform post-creation processing for collection mappings.
|
||||||
|
*
|
||||||
|
* @apiNote Called after all {@linkplain InFlightEntityMappingType} processing has
|
||||||
|
* occurred, allowing access to the runtime mapping model of the entities.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface InFlightCollectionMapping {
|
||||||
|
/**
|
||||||
|
* After all hierarchy types have been linked, this method is called to allow the
|
||||||
|
* mapping model to be prepared which generally includes creating attribute mapping
|
||||||
|
* descriptors, identifier mapping descriptor, etc.
|
||||||
|
*/
|
||||||
|
default void prepareMappingModel(MappingModelCreationProcess creationProcess) {
|
||||||
|
// by default do nothing - support for legacy impls
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ package org.hibernate.metamodel.mapping.internal;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Defines the ability to perform post-creation processing for entity mappings.
|
||||||
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface InFlightEntityMappingType extends EntityMappingType {
|
public interface InFlightEntityMappingType extends EntityMappingType {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.hibernate.metamodel.mapping.NonTransientException;
|
||||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
import org.hibernate.metamodel.model.domain.internal.EntityPersisterConcurrentMap;
|
import org.hibernate.metamodel.model.domain.internal.EntityPersisterConcurrentMap;
|
||||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||||
|
|
||||||
|
@ -32,15 +33,18 @@ public class MappingModelCreationProcess {
|
||||||
*/
|
*/
|
||||||
public static void process(
|
public static void process(
|
||||||
EntityPersisterConcurrentMap entityPersisterMap,
|
EntityPersisterConcurrentMap entityPersisterMap,
|
||||||
|
Map<String, CollectionPersister> collectionPersisterMap,
|
||||||
RuntimeModelCreationContext creationContext) {
|
RuntimeModelCreationContext creationContext) {
|
||||||
final MappingModelCreationProcess process = new MappingModelCreationProcess(
|
final MappingModelCreationProcess process = new MappingModelCreationProcess(
|
||||||
entityPersisterMap,
|
entityPersisterMap,
|
||||||
|
collectionPersisterMap,
|
||||||
creationContext
|
creationContext
|
||||||
);
|
);
|
||||||
process.execute();
|
process.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final EntityPersisterConcurrentMap entityPersisterMap;
|
private final EntityPersisterConcurrentMap entityPersisterMap;
|
||||||
|
private final Map<String, CollectionPersister> collectionPersisterMap;
|
||||||
private final RuntimeModelCreationContext creationContext;
|
private final RuntimeModelCreationContext creationContext;
|
||||||
|
|
||||||
private String currentlyProcessingRole;
|
private String currentlyProcessingRole;
|
||||||
|
@ -48,8 +52,10 @@ public class MappingModelCreationProcess {
|
||||||
|
|
||||||
private MappingModelCreationProcess(
|
private MappingModelCreationProcess(
|
||||||
EntityPersisterConcurrentMap entityPersisterMap,
|
EntityPersisterConcurrentMap entityPersisterMap,
|
||||||
|
Map<String, CollectionPersister> collectionPersisterMap,
|
||||||
RuntimeModelCreationContext creationContext) {
|
RuntimeModelCreationContext creationContext) {
|
||||||
this.entityPersisterMap = entityPersisterMap;
|
this.entityPersisterMap = entityPersisterMap;
|
||||||
|
this.collectionPersisterMap = collectionPersisterMap;
|
||||||
this.creationContext = creationContext;
|
this.creationContext = creationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +89,12 @@ public class MappingModelCreationProcess {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for ( CollectionPersister collectionPersister : collectionPersisterMap.values() ) {
|
||||||
|
if ( collectionPersister instanceof InFlightCollectionMapping ) {
|
||||||
|
((InFlightCollectionMapping) collectionPersister).prepareMappingModel( this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
executePostInitCallbacks();
|
executePostInitCallbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
|
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
|
||||||
|
import org.hibernate.metamodel.mapping.DiscriminatorValueDetails;
|
||||||
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
|
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.type.descriptor.java.CharacterJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.StringJavaType;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR;
|
||||||
|
import static org.hibernate.persister.entity.DiscriminatorHelper.NULL_DISCRIMINATOR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DiscriminatorConverter for use with {@linkplain org.hibernate.type.AnyDiscriminatorValueStrategy#MIXED}
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class MixedDiscriminatorConverter<O,R> extends DiscriminatorConverter<O,R> {
|
||||||
|
private final NavigableRole discriminatorRole;
|
||||||
|
private final Map<Object, DiscriminatorValueDetails> detailsByValue;
|
||||||
|
private final Map<String,DiscriminatorValueDetails> detailsByEntityName;
|
||||||
|
private final MappingMetamodelImplementor mappingMetamodel;
|
||||||
|
|
||||||
|
public MixedDiscriminatorConverter(
|
||||||
|
NavigableRole discriminatorRole,
|
||||||
|
JavaType<O> domainJavaType,
|
||||||
|
JavaType<R> relationalJavaType,
|
||||||
|
Map<Object,String> explicitValueMappings,
|
||||||
|
MappingMetamodelImplementor mappingMetamodel) {
|
||||||
|
super( discriminatorRole.getFullPath(), domainJavaType, relationalJavaType );
|
||||||
|
this.discriminatorRole = discriminatorRole;
|
||||||
|
this.mappingMetamodel = mappingMetamodel;
|
||||||
|
|
||||||
|
this.detailsByValue = CollectionHelper.concurrentMap( explicitValueMappings.size() );
|
||||||
|
this.detailsByEntityName = CollectionHelper.concurrentMap( explicitValueMappings.size() );
|
||||||
|
explicitValueMappings.forEach( (value,entityName) -> {
|
||||||
|
String importedEntityName = mappingMetamodel.getImportedName( entityName );
|
||||||
|
final EntityPersister entityDescriptor = mappingMetamodel.getEntityDescriptor( importedEntityName );
|
||||||
|
register( value, entityDescriptor );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiscriminatorValueDetails register(Object value, EntityPersister entityDescriptor) {
|
||||||
|
final DiscriminatorValueDetails details = new DiscriminatorValueDetailsImpl( value, entityDescriptor );
|
||||||
|
detailsByValue.put( value, details );
|
||||||
|
detailsByEntityName.put( entityDescriptor.getEntityName(), details );
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DiscriminatorValueDetails getDetailsForDiscriminatorValue(Object relationalForm) {
|
||||||
|
if ( relationalForm == null ) {
|
||||||
|
return detailsByValue.get( NULL_DISCRIMINATOR );
|
||||||
|
}
|
||||||
|
|
||||||
|
final DiscriminatorValueDetails existing = detailsByValue.get( relationalForm );
|
||||||
|
if ( existing != null ) {
|
||||||
|
// an explicit or previously-resolved mapping
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
|
||||||
|
final DiscriminatorValueDetails notNullMatch = detailsByValue.get( NOT_NULL_DISCRIMINATOR );
|
||||||
|
if ( notNullMatch != null ) {
|
||||||
|
return notNullMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( relationalForm.getClass().isEnum() ) {
|
||||||
|
final Object enumValue;
|
||||||
|
if ( getRelationalJavaType() instanceof StringJavaType ) {
|
||||||
|
enumValue = ( (Enum) relationalForm ).name();
|
||||||
|
}
|
||||||
|
else if ( getRelationalJavaType() instanceof CharacterJavaType ) {
|
||||||
|
enumValue = ( (Enum) relationalForm ).name().charAt( 0 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enumValue = ( (Enum) relationalForm ).ordinal();
|
||||||
|
}
|
||||||
|
final DiscriminatorValueDetails enumMatch = detailsByValue.get( enumValue );
|
||||||
|
if ( enumMatch != null ) {
|
||||||
|
return enumMatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( relationalForm instanceof String assumedEntityName ) {
|
||||||
|
// Assume the relational form is the entity name
|
||||||
|
final EntityPersister persister = mappingMetamodel.findEntityDescriptor( assumedEntityName );
|
||||||
|
if ( persister != null ) {
|
||||||
|
return register( assumedEntityName, persister );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new HibernateException( "Cannot interpret discriminator value (" + discriminatorRole + ") : " + relationalForm );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DiscriminatorValueDetails getDetailsForEntityName(String entityName) {
|
||||||
|
final DiscriminatorValueDetails existing = detailsByEntityName.get( entityName );
|
||||||
|
if ( existing != null) {
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
|
||||||
|
final EntityPersister entityDescriptor = mappingMetamodel.getEntityDescriptor( entityName );
|
||||||
|
return register( entityName, entityDescriptor );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEachValueDetail(Consumer<DiscriminatorValueDetails> consumer) {
|
||||||
|
detailsByEntityName.forEach( (value, detail) -> consumer.accept( detail ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> X fromValueDetails(Function<DiscriminatorValueDetails, X> handler) {
|
||||||
|
for ( DiscriminatorValueDetails detail : detailsByEntityName.values() ) {
|
||||||
|
final X result = handler.apply( detail );
|
||||||
|
if ( result != null ) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,8 +6,6 @@ package org.hibernate.metamodel.model.domain.internal;
|
||||||
|
|
||||||
import org.hibernate.mapping.Any;
|
import org.hibernate.mapping.Any;
|
||||||
import org.hibernate.mapping.Column;
|
import org.hibernate.mapping.Column;
|
||||||
import org.hibernate.metamodel.mapping.DefaultDiscriminatorConverter;
|
|
||||||
import org.hibernate.metamodel.mapping.MappedDiscriminatorConverter;
|
|
||||||
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
|
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
import org.hibernate.metamodel.model.domain.SimpleDomainType;
|
import org.hibernate.metamodel.model.domain.SimpleDomainType;
|
||||||
|
@ -15,12 +13,13 @@ import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||||
import org.hibernate.type.AnyType;
|
import org.hibernate.type.AnyType;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.MetaType;
|
import org.hibernate.type.MetaType;
|
||||||
import org.hibernate.type.descriptor.java.ClassJavaType;
|
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
|
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.hibernate.metamodel.mapping.internal.AnyDiscriminatorPart.determineDiscriminatorConverter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -42,21 +41,14 @@ public class AnyMappingDomainTypeImpl<T> implements AnyMappingDomainType<T> {
|
||||||
final BasicType discriminatorBaseType = (BasicType) discriminatorType.getBaseType();
|
final BasicType discriminatorBaseType = (BasicType) discriminatorType.getBaseType();
|
||||||
final NavigableRole navigableRole = resolveNavigableRole( bootAnyMapping );
|
final NavigableRole navigableRole = resolveNavigableRole( bootAnyMapping );
|
||||||
|
|
||||||
anyDiscriminatorType = new ConvertedBasicTypeImpl<>(
|
anyDiscriminatorType = new ConvertedBasicTypeImpl(
|
||||||
navigableRole.getFullPath(),
|
navigableRole.getFullPath(),
|
||||||
discriminatorBaseType.getJdbcType(),
|
discriminatorBaseType.getJdbcType(),
|
||||||
bootAnyMapping.getMetaValues().isEmpty()
|
determineDiscriminatorConverter(
|
||||||
? DefaultDiscriminatorConverter.fromMappingMetamodel(
|
|
||||||
navigableRole,
|
navigableRole,
|
||||||
ClassJavaType.INSTANCE,
|
|
||||||
discriminatorBaseType,
|
|
||||||
mappingMetamodel
|
|
||||||
)
|
|
||||||
: MappedDiscriminatorConverter.fromValueMappings(
|
|
||||||
navigableRole,
|
|
||||||
ClassJavaType.INSTANCE,
|
|
||||||
discriminatorBaseType,
|
discriminatorBaseType,
|
||||||
bootAnyMapping.getMetaValues(),
|
bootAnyMapping.getMetaValues(),
|
||||||
|
discriminatorType.getValueStrategy(),
|
||||||
mappingMetamodel
|
mappingMetamodel
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -195,7 +195,7 @@ public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// after *all* persisters and named queries are registered
|
// after *all* persisters and named queries are registered
|
||||||
|
|
||||||
MappingModelCreationProcess.process( entityPersisterMap, context );
|
MappingModelCreationProcess.process( entityPersisterMap, collectionPersisterMap, context );
|
||||||
|
|
||||||
for ( EntityPersister persister : entityPersisterMap.values() ) {
|
for ( EntityPersister persister : entityPersisterMap.values() ) {
|
||||||
persister.postInstantiate();
|
persister.postInstantiate();
|
||||||
|
|
|
@ -4,18 +4,8 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.persister.collection;
|
package org.hibernate.persister.collection;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import jakarta.persistence.metamodel.PluralAttribute;
|
||||||
import java.sql.ResultSet;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.Filter;
|
import org.hibernate.Filter;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
@ -60,7 +50,6 @@ import org.hibernate.loader.ast.internal.LoaderSqlAstCreationState;
|
||||||
import org.hibernate.loader.ast.spi.BatchLoaderFactory;
|
import org.hibernate.loader.ast.spi.BatchLoaderFactory;
|
||||||
import org.hibernate.loader.ast.spi.CollectionLoader;
|
import org.hibernate.loader.ast.spi.CollectionLoader;
|
||||||
import org.hibernate.mapping.Any;
|
import org.hibernate.mapping.Any;
|
||||||
import org.hibernate.mapping.BasicValue;
|
|
||||||
import org.hibernate.mapping.Collection;
|
import org.hibernate.mapping.Collection;
|
||||||
import org.hibernate.mapping.Column;
|
import org.hibernate.mapping.Column;
|
||||||
import org.hibernate.mapping.Formula;
|
import org.hibernate.mapping.Formula;
|
||||||
|
@ -72,15 +61,21 @@ import org.hibernate.mapping.Selectable;
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.mapping.Value;
|
import org.hibernate.mapping.Value;
|
||||||
import org.hibernate.metamodel.CollectionClassification;
|
import org.hibernate.metamodel.CollectionClassification;
|
||||||
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||||
|
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
|
||||||
|
import org.hibernate.metamodel.mapping.DiscriminatorValueDetails;
|
||||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.internal.EmbeddedCollectionPart;
|
import org.hibernate.metamodel.mapping.internal.EmbeddedCollectionPart;
|
||||||
import org.hibernate.metamodel.mapping.internal.EntityCollectionPart;
|
import org.hibernate.metamodel.mapping.internal.EntityCollectionPart;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.InFlightCollectionMapping;
|
||||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
|
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
||||||
import org.hibernate.metamodel.mapping.internal.PluralAttributeMappingImpl;
|
import org.hibernate.metamodel.mapping.internal.PluralAttributeMappingImpl;
|
||||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
|
@ -129,15 +124,25 @@ import org.hibernate.sql.model.jdbc.JdbcMutationOperation;
|
||||||
import org.hibernate.sql.results.graph.internal.ImmutableFetchList;
|
import org.hibernate.sql.results.graph.internal.ImmutableFetchList;
|
||||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||||
import org.hibernate.type.AnyType;
|
import org.hibernate.type.AnyType;
|
||||||
import org.hibernate.type.BasicType;
|
|
||||||
import org.hibernate.type.CollectionType;
|
import org.hibernate.type.CollectionType;
|
||||||
import org.hibernate.type.ComponentType;
|
import org.hibernate.type.ComponentType;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
import org.hibernate.type.EntityType;
|
import org.hibernate.type.EntityType;
|
||||||
import org.hibernate.type.MetaType;
|
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static org.hibernate.internal.util.StringHelper.getNonEmptyOrConjunctionIfBothNonEmpty;
|
import static org.hibernate.internal.util.StringHelper.getNonEmptyOrConjunctionIfBothNonEmpty;
|
||||||
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
|
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
|
||||||
|
@ -154,7 +159,7 @@ import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER
|
||||||
*/
|
*/
|
||||||
@Internal
|
@Internal
|
||||||
public abstract class AbstractCollectionPersister
|
public abstract class AbstractCollectionPersister
|
||||||
implements CollectionPersister, CollectionMutationTarget, PluralAttributeMappingImpl.Aware, FetchProfileAffectee, Joinable {
|
implements CollectionPersister, InFlightCollectionMapping, CollectionMutationTarget, PluralAttributeMappingImpl.Aware, FetchProfileAffectee, Joinable {
|
||||||
|
|
||||||
private final NavigableRole navigableRole;
|
private final NavigableRole navigableRole;
|
||||||
private final CollectionSemantics<?,?> collectionSemantics;
|
private final CollectionSemantics<?,?> collectionSemantics;
|
||||||
|
@ -164,13 +169,13 @@ public abstract class AbstractCollectionPersister
|
||||||
protected final String qualifiedTableName;
|
protected final String qualifiedTableName;
|
||||||
private final CollectionTableMapping tableMapping;
|
private final CollectionTableMapping tableMapping;
|
||||||
|
|
||||||
private final String sqlSelectSizeString;
|
private String sqlSelectSizeString;
|
||||||
private final String sqlDetectRowByIndexString;
|
private String sqlDetectRowByIndexString;
|
||||||
private final String sqlDetectRowByElementString;
|
private String sqlDetectRowByElementString;
|
||||||
|
|
||||||
protected final boolean hasWhere;
|
protected boolean hasWhere;
|
||||||
protected final String sqlWhereString;
|
protected String sqlWhereString;
|
||||||
private final String sqlWhereStringTemplate;
|
private String sqlWhereStringTemplate;
|
||||||
|
|
||||||
private final boolean hasOrder;
|
private final boolean hasOrder;
|
||||||
private final boolean hasManyToManyOrder;
|
private final boolean hasManyToManyOrder;
|
||||||
|
@ -244,10 +249,14 @@ public abstract class AbstractCollectionPersister
|
||||||
private PluralAttributeMapping attributeMapping;
|
private PluralAttributeMapping attributeMapping;
|
||||||
private volatile Set<String> affectingFetchProfiles;
|
private volatile Set<String> affectingFetchProfiles;
|
||||||
|
|
||||||
|
private Collection collectionBootDescriptor;
|
||||||
|
|
||||||
public AbstractCollectionPersister(
|
public AbstractCollectionPersister(
|
||||||
Collection collectionBootDescriptor,
|
Collection collectionBootDescriptor,
|
||||||
@Nullable CollectionDataAccess cacheAccessStrategy,
|
@Nullable CollectionDataAccess cacheAccessStrategy,
|
||||||
RuntimeModelCreationContext creationContext) throws MappingException, CacheException {
|
RuntimeModelCreationContext creationContext) throws MappingException, CacheException {
|
||||||
|
this.collectionBootDescriptor = collectionBootDescriptor;
|
||||||
|
|
||||||
this.factory = creationContext.getSessionFactory();
|
this.factory = creationContext.getSessionFactory();
|
||||||
this.collectionSemantics = creationContext.getBootstrapContext()
|
this.collectionSemantics = creationContext.getBootstrapContext()
|
||||||
.getMetadataBuildingOptions()
|
.getMetadataBuildingOptions()
|
||||||
|
@ -295,49 +304,6 @@ public abstract class AbstractCollectionPersister
|
||||||
spaces[i] = tables.next();
|
spaces[i] = tables.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
String where = collectionBootDescriptor.getWhere();
|
|
||||||
/*
|
|
||||||
* Add the predicate on the role in the WHERE clause before creating the SQL queries.
|
|
||||||
*/
|
|
||||||
if ( mappedByProperty != null && elementType instanceof EntityType ) {
|
|
||||||
final String entityName = ( (EntityType) elementType ).getAssociatedEntityName();
|
|
||||||
final PersistentClass persistentClass = creationContext.getBootModel().getEntityBinding( entityName );
|
|
||||||
final Property property = persistentClass.getRecursiveProperty( mappedByProperty );
|
|
||||||
final Value propertyValue = property.getValue();
|
|
||||||
if ( propertyValue instanceof Any ) {
|
|
||||||
final Any any = (Any) propertyValue;
|
|
||||||
final BasicValue discriminatorDescriptor = any.getDiscriminatorDescriptor();
|
|
||||||
final AnyType anyType = any.getType();
|
|
||||||
final MetaType metaType = (MetaType) anyType.getDiscriminatorType();
|
|
||||||
final Object discriminatorValue = metaType.getEntityNameToDiscriminatorValueMap().get( ownerPersister.getEntityName() );
|
|
||||||
final BasicType<Object> discriminatorBaseType = (BasicType<Object>) metaType.getBaseType();
|
|
||||||
final String discriminatorLiteral = discriminatorBaseType.getJdbcLiteralFormatter().toJdbcLiteral(
|
|
||||||
discriminatorValue,
|
|
||||||
creationContext.getDialect(),
|
|
||||||
creationContext.getSessionFactory().getWrapperOptions()
|
|
||||||
);
|
|
||||||
where = getNonEmptyOrConjunctionIfBothNonEmpty(
|
|
||||||
where,
|
|
||||||
discriminatorDescriptor.getColumn().getText() + "=" + discriminatorLiteral
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( StringHelper.isNotEmpty( where ) ) {
|
|
||||||
hasWhere = true;
|
|
||||||
sqlWhereString = "(" + where + ")";
|
|
||||||
sqlWhereStringTemplate = Template.renderWhereStringTemplate(
|
|
||||||
sqlWhereString,
|
|
||||||
dialect,
|
|
||||||
creationContext.getTypeConfiguration()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
hasWhere = false;
|
|
||||||
sqlWhereString = null;
|
|
||||||
sqlWhereStringTemplate = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasOrphanDelete = collectionBootDescriptor.hasOrphanDelete();
|
hasOrphanDelete = collectionBootDescriptor.hasOrphanDelete();
|
||||||
|
|
||||||
batchSize = collectionBootDescriptor.getBatchSize() < 0
|
batchSize = collectionBootDescriptor.getBatchSize() < 0
|
||||||
|
@ -512,12 +478,6 @@ public abstract class AbstractCollectionPersister
|
||||||
identifierGenerator = null;
|
identifierGenerator = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATE THE SQL:
|
|
||||||
|
|
||||||
sqlSelectSizeString = generateSelectSizeString( collectionBootDescriptor.isIndexed() && !collectionBootDescriptor.isMap() );
|
|
||||||
sqlDetectRowByIndexString = generateDetectRowByIndexString();
|
|
||||||
sqlDetectRowByElementString = generateDetectRowByElementString();
|
|
||||||
|
|
||||||
isLazy = collectionBootDescriptor.isLazy();
|
isLazy = collectionBootDescriptor.isLazy();
|
||||||
isExtraLazy = collectionBootDescriptor.isExtraLazy();
|
isExtraLazy = collectionBootDescriptor.isExtraLazy();
|
||||||
|
|
||||||
|
@ -592,6 +552,119 @@ public abstract class AbstractCollectionPersister
|
||||||
&& creationContext.getDialect().supportsCascadeDelete();
|
&& creationContext.getDialect().supportsCascadeDelete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepareMappingModel(MappingModelCreationProcess creationProcess) {
|
||||||
|
if ( mappedByProperty != null && elementType instanceof EntityType ) {
|
||||||
|
final String entityName = ((EntityType) elementType).getAssociatedEntityName();
|
||||||
|
|
||||||
|
final PersistentClass persistentClass = creationProcess.getCreationContext().getBootModel().getEntityBinding( entityName );
|
||||||
|
final Property property = persistentClass.getRecursiveProperty( mappedByProperty );
|
||||||
|
final Value propertyValue = property.getValue();
|
||||||
|
|
||||||
|
if ( propertyValue instanceof Any ) {
|
||||||
|
// we want to delay processing of where-fragment, and therefore affected SQL, until
|
||||||
|
// all model parts are ready so that we can access details about the ANY discriminator
|
||||||
|
creationProcess.registerInitializationCallback(
|
||||||
|
"Where-fragment handling for ANY inverse mapping : " + navigableRole,
|
||||||
|
() -> {
|
||||||
|
final EntityPersister entityPersister = creationProcess.getEntityPersister( entityName );
|
||||||
|
delayedWhereFragmentProcessing( entityPersister, mappedByProperty, collectionBootDescriptor, creationProcess );
|
||||||
|
buildStaticWhereFragmentSensitiveSql();
|
||||||
|
collectionBootDescriptor = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( StringHelper.isNotEmpty( collectionBootDescriptor.getWhere() ) ) {
|
||||||
|
hasWhere = true;
|
||||||
|
sqlWhereString = "(" + collectionBootDescriptor.getWhere() + ")";
|
||||||
|
sqlWhereStringTemplate = Template.renderWhereStringTemplate(
|
||||||
|
sqlWhereString,
|
||||||
|
dialect,
|
||||||
|
creationProcess.getCreationContext().getTypeConfiguration()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
buildStaticWhereFragmentSensitiveSql();
|
||||||
|
collectionBootDescriptor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void delayedWhereFragmentProcessing(
|
||||||
|
EntityPersister entityPersister,
|
||||||
|
String mappedByProperty,
|
||||||
|
Collection collectionBootDescriptor,
|
||||||
|
MappingModelCreationProcess creationProcess) {
|
||||||
|
String where = collectionBootDescriptor.getWhere();
|
||||||
|
|
||||||
|
final AttributeMapping mappedByAttribute = resolveMappedBy( entityPersister, mappedByProperty, creationProcess );
|
||||||
|
if ( mappedByAttribute instanceof DiscriminatedAssociationAttributeMapping ) {
|
||||||
|
final DiscriminatedAssociationAttributeMapping anyMapping = (DiscriminatedAssociationAttributeMapping) mappedByAttribute;
|
||||||
|
final DiscriminatorConverter<?, ?> valueConverter = anyMapping.getDiscriminatorMapping().getValueConverter();
|
||||||
|
final DiscriminatorValueDetails discriminatorValueDetails = valueConverter.getDetailsForEntityName( ownerPersister.getEntityName() );
|
||||||
|
//noinspection unchecked
|
||||||
|
final String discriminatorLiteral = anyMapping.getDiscriminatorMapping().getUnderlyingJdbcMapping().getJdbcLiteralFormatter().toJdbcLiteral(
|
||||||
|
discriminatorValueDetails.getValue(),
|
||||||
|
creationProcess.getCreationContext().getDialect(),
|
||||||
|
creationProcess.getCreationContext().getSessionFactory().getWrapperOptions()
|
||||||
|
);
|
||||||
|
where = getNonEmptyOrConjunctionIfBothNonEmpty(
|
||||||
|
where,
|
||||||
|
anyMapping.getDiscriminatorMapping().getSelectableName() + "=" + discriminatorLiteral
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( StringHelper.isNotEmpty( where ) ) {
|
||||||
|
hasWhere = true;
|
||||||
|
sqlWhereString = "(" + where + ")";
|
||||||
|
sqlWhereStringTemplate = Template.renderWhereStringTemplate(
|
||||||
|
sqlWhereString,
|
||||||
|
dialect,
|
||||||
|
creationProcess.getCreationContext().getTypeConfiguration()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildStaticWhereFragmentSensitiveSql() {
|
||||||
|
sqlSelectSizeString = generateSelectSizeString( hasIndex() && !isMap() );
|
||||||
|
sqlDetectRowByIndexString = generateDetectRowByIndexString();
|
||||||
|
sqlDetectRowByElementString = generateDetectRowByElementString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMap() {
|
||||||
|
return collectionSemantics.getCollectionClassification().toJpaClassification() == PluralAttribute.CollectionType.MAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AttributeMapping resolveMappedBy(EntityPersister entityPersister, String mappedByProperty, MappingModelCreationProcess creationProcess) {
|
||||||
|
final StringTokenizer propertyPathParts = new StringTokenizer( mappedByProperty, ".", false );
|
||||||
|
assert propertyPathParts.countTokens() > 0;
|
||||||
|
|
||||||
|
if ( propertyPathParts.countTokens() == 1 ) {
|
||||||
|
return entityPersister.findAttributeMapping( propertyPathParts.nextToken() );
|
||||||
|
}
|
||||||
|
|
||||||
|
ManagedMappingType source = entityPersister;
|
||||||
|
while ( propertyPathParts.hasMoreTokens() ) {
|
||||||
|
final String partName = propertyPathParts.nextToken();
|
||||||
|
final AttributeMapping namedPart = source.findAttributeMapping( partName );
|
||||||
|
if ( !propertyPathParts.hasMoreTokens() ) {
|
||||||
|
return namedPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
source = (ManagedMappingType) namedPart.getPartMappingType();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new MappingException(
|
||||||
|
String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"Unable to resolve mapped-by path : (%s) %s",
|
||||||
|
entityPersister.getEntityName(),
|
||||||
|
mappedByProperty
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private BeforeExecutionGenerator createGenerator(RuntimeModelCreationContext context, IdentifierCollection collection) {
|
private BeforeExecutionGenerator createGenerator(RuntimeModelCreationContext context, IdentifierCollection collection) {
|
||||||
final Generator generator =
|
final Generator generator =
|
||||||
collection.getIdentifier()
|
collection.getIdentifier()
|
||||||
|
|
|
@ -165,7 +165,6 @@ import org.hibernate.metamodel.mapping.EntityVersionMapping;
|
||||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||||
import org.hibernate.metamodel.mapping.MappedDiscriminatorConverter;
|
|
||||||
import org.hibernate.metamodel.mapping.MappingModelHelper;
|
import org.hibernate.metamodel.mapping.MappingModelHelper;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.metamodel.mapping.NaturalIdMapping;
|
import org.hibernate.metamodel.mapping.NaturalIdMapping;
|
||||||
|
@ -185,6 +184,7 @@ import org.hibernate.loader.ast.internal.EntityConcreteTypeLoader;
|
||||||
import org.hibernate.metamodel.mapping.internal.EntityRowIdMappingImpl;
|
import org.hibernate.metamodel.mapping.internal.EntityRowIdMappingImpl;
|
||||||
import org.hibernate.metamodel.mapping.internal.EntityVersionMappingImpl;
|
import org.hibernate.metamodel.mapping.internal.EntityVersionMappingImpl;
|
||||||
import org.hibernate.metamodel.mapping.internal.ExplicitColumnDiscriminatorMappingImpl;
|
import org.hibernate.metamodel.mapping.internal.ExplicitColumnDiscriminatorMappingImpl;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.ExplicitDiscriminatorConverter;
|
||||||
import org.hibernate.metamodel.mapping.internal.GeneratedValuesProcessor;
|
import org.hibernate.metamodel.mapping.internal.GeneratedValuesProcessor;
|
||||||
import org.hibernate.metamodel.mapping.internal.ImmutableAttributeMappingList;
|
import org.hibernate.metamodel.mapping.internal.ImmutableAttributeMappingList;
|
||||||
import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
|
import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
|
||||||
|
@ -337,6 +337,7 @@ public abstract class AbstractEntityPersister
|
||||||
private final EntityEntryFactory entityEntryFactory;
|
private final EntityEntryFactory entityEntryFactory;
|
||||||
|
|
||||||
private final String sqlAliasStem;
|
private final String sqlAliasStem;
|
||||||
|
private final String jpaEntityName;
|
||||||
|
|
||||||
private SingleIdEntityLoader<?> singleIdLoader;
|
private SingleIdEntityLoader<?> singleIdLoader;
|
||||||
private MultiIdEntityLoader<?> multiIdLoader;
|
private MultiIdEntityLoader<?> multiIdLoader;
|
||||||
|
@ -473,6 +474,7 @@ public abstract class AbstractEntityPersister
|
||||||
final EntityDataAccess cacheAccessStrategy,
|
final EntityDataAccess cacheAccessStrategy,
|
||||||
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
|
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
|
||||||
final RuntimeModelCreationContext creationContext) throws HibernateException {
|
final RuntimeModelCreationContext creationContext) throws HibernateException {
|
||||||
|
this.jpaEntityName = persistentClass.getJpaEntityName();
|
||||||
|
|
||||||
//set it here, but don't call it, since it's still uninitialized!
|
//set it here, but don't call it, since it's still uninitialized!
|
||||||
factory = creationContext.getSessionFactory();
|
factory = creationContext.getSessionFactory();
|
||||||
|
@ -2279,10 +2281,10 @@ public abstract class AbstractEntityPersister
|
||||||
}
|
}
|
||||||
|
|
||||||
//noinspection rawtypes
|
//noinspection rawtypes
|
||||||
final DiscriminatorConverter converter = MappedDiscriminatorConverter.fromValueMappings(
|
final DiscriminatorConverter converter = new ExplicitDiscriminatorConverter(
|
||||||
getNavigableRole().append( EntityDiscriminatorMapping.DISCRIMINATOR_ROLE_NAME ),
|
getNavigableRole().append( EntityDiscriminatorMapping.DISCRIMINATOR_ROLE_NAME ),
|
||||||
domainJavaType,
|
domainJavaType,
|
||||||
underlingJdbcMapping,
|
underlingJdbcMapping.getRelationalJavaType(),
|
||||||
getSubclassByDiscriminatorValue(),
|
getSubclassByDiscriminatorValue(),
|
||||||
factory.getMappingMetamodel()
|
factory.getMappingMetamodel()
|
||||||
);
|
);
|
||||||
|
@ -3776,6 +3778,11 @@ public abstract class AbstractEntityPersister
|
||||||
return entityMetamodel.getName();
|
return entityMetamodel.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getJpaEntityName() {
|
||||||
|
return jpaEntityName;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInherited() {
|
public boolean isInherited() {
|
||||||
return entityMetamodel.isInherited();
|
return entityMetamodel.isInherited();
|
||||||
|
|
|
@ -10,6 +10,8 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.Incubating;
|
import org.hibernate.Incubating;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
@ -37,6 +39,7 @@ import org.hibernate.generator.values.GeneratedValues;
|
||||||
import org.hibernate.id.IdentifierGenerator;
|
import org.hibernate.id.IdentifierGenerator;
|
||||||
import org.hibernate.internal.FilterAliasGenerator;
|
import org.hibernate.internal.FilterAliasGenerator;
|
||||||
import org.hibernate.internal.TableGroupFilterAliasGenerator;
|
import org.hibernate.internal.TableGroupFilterAliasGenerator;
|
||||||
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.loader.ast.spi.MultiIdLoadOptions;
|
import org.hibernate.loader.ast.spi.MultiIdLoadOptions;
|
||||||
import org.hibernate.loader.ast.spi.MultiNaturalIdLoader;
|
import org.hibernate.loader.ast.spi.MultiNaturalIdLoader;
|
||||||
import org.hibernate.loader.ast.spi.NaturalIdLoader;
|
import org.hibernate.loader.ast.spi.NaturalIdLoader;
|
||||||
|
@ -178,6 +181,16 @@ public interface EntityPersister extends EntityMappingType, EntityMutationTarget
|
||||||
*/
|
*/
|
||||||
String getEntityName();
|
String getEntityName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@linkplain Entity#name() JPA entity name}, if one, associated with the entity.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getJpaEntityName();
|
||||||
|
|
||||||
|
default String getImportedName() {
|
||||||
|
return getJpaEntityName() != null ? getJpaEntityName() : StringHelper.unqualifyEntityName( getEntityName() );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The strategy to use for SQM mutation statements where the target entity
|
* The strategy to use for SQM mutation statements where the target entity
|
||||||
* has multiple tables. Returns {@code null} to indicate that the entity
|
* has multiple tables. Returns {@code null} to indicate that the entity
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.type;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.AnyDiscriminatorValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes how to deal with discriminator values in regard to
|
||||||
|
* a {@linkplain org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart ANY mapping}
|
||||||
|
*
|
||||||
|
* @see AnyDiscriminatorValue
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public enum AnyDiscriminatorValueStrategy {
|
||||||
|
/**
|
||||||
|
* Pick between {@link #IMPLICIT} and {@link #EXPLICIT} based on
|
||||||
|
* presence or not of {@link AnyDiscriminatorValue}. The default
|
||||||
|
* (and legacy) behavior.
|
||||||
|
*/
|
||||||
|
AUTO,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expect explicit, complete mapping of discriminator values using
|
||||||
|
* one-or-more {@link AnyDiscriminatorValue}.
|
||||||
|
*
|
||||||
|
* @implNote With this option, it is considered an error if, at runtime,
|
||||||
|
* we encounter an entity type not explicitly mapped with a
|
||||||
|
* {@link AnyDiscriminatorValue}.
|
||||||
|
*/
|
||||||
|
EXPLICIT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expect no {@link AnyDiscriminatorValue}. The entity name of the associated
|
||||||
|
* entity is used as the discriminator value.
|
||||||
|
*
|
||||||
|
* @implNote With this option, it is considered illegal to specify
|
||||||
|
* any {@link AnyDiscriminatorValue} mappings.
|
||||||
|
*/
|
||||||
|
IMPLICIT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows a combination of {@linkplain #EXPLICIT explicit} and {@linkplain #IMPLICIT implicit}
|
||||||
|
* discriminator value mappings. If an entity is mapped using an explicit
|
||||||
|
* {@link AnyDiscriminatorValue} mapping, the associated discriminator value is used.
|
||||||
|
* Otherwise, the entity name is used.
|
||||||
|
*
|
||||||
|
* @implNote This option is roughly the same as {@link #EXPLICIT} except
|
||||||
|
* that an implicit mapping using the entity name is used when a matching
|
||||||
|
* explicit {@link AnyDiscriminatorValue} mapping is not found.
|
||||||
|
*/
|
||||||
|
MIXED
|
||||||
|
}
|
|
@ -43,16 +43,37 @@ import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
|
||||||
public class AnyType extends AbstractType implements CompositeType, AssociationType {
|
public class AnyType extends AbstractType implements CompositeType, AssociationType {
|
||||||
private final TypeConfiguration typeConfiguration;
|
private final TypeConfiguration typeConfiguration;
|
||||||
private final Type identifierType;
|
private final Type identifierType;
|
||||||
private final Type discriminatorType;
|
private final MetaType discriminatorType;
|
||||||
private final boolean eager;
|
private final boolean eager;
|
||||||
|
|
||||||
public AnyType(TypeConfiguration typeConfiguration, Type discriminatorType, Type identifierType, boolean lazy) {
|
public AnyType(TypeConfiguration typeConfiguration, MetaType discriminatorType, Type identifierType, boolean lazy) {
|
||||||
this.typeConfiguration = typeConfiguration;
|
this.typeConfiguration = typeConfiguration;
|
||||||
this.discriminatorType = discriminatorType;
|
this.discriminatorType = discriminatorType;
|
||||||
this.identifierType = identifierType;
|
this.identifierType = identifierType;
|
||||||
this.eager = !lazy;
|
this.eager = !lazy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@linkplain AnyType#AnyType(TypeConfiguration, MetaType, Type, boolean)} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public AnyType(TypeConfiguration typeConfiguration, Type discriminatorType, Type identifierType, boolean lazy) {
|
||||||
|
this(
|
||||||
|
typeConfiguration,
|
||||||
|
wrapDiscriminatorType( discriminatorType ),
|
||||||
|
identifierType,
|
||||||
|
lazy
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MetaType wrapDiscriminatorType(Type discriminatorType) {
|
||||||
|
if ( discriminatorType instanceof MetaType metaType ) {
|
||||||
|
return metaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MetaType( discriminatorType, AnyDiscriminatorValueStrategy.AUTO, null );
|
||||||
|
}
|
||||||
|
|
||||||
public Type getIdentifierType() {
|
public Type getIdentifierType() {
|
||||||
return identifierType;
|
return identifierType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,47 +4,68 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.Internal;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
|
||||||
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
|
import java.sql.PreparedStatement;
|
||||||
import org.hibernate.persister.entity.DiscriminatorMetadata;
|
import java.sql.SQLException;
|
||||||
import org.hibernate.persister.entity.DiscriminatorType;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*
|
|
||||||
* @deprecated The functionality of MetaType, {@link DiscriminatorType} and {@link DiscriminatorMetadata} have been
|
|
||||||
* consolidated into {@link EntityDiscriminatorMapping} and {@link DiscriminatorConverter}
|
|
||||||
*/
|
*/
|
||||||
@Deprecated( since = "6.2", forRemoval = true )
|
@Internal
|
||||||
public class MetaType extends AbstractType {
|
public class MetaType extends AbstractType {
|
||||||
public static final String[] REGISTRATION_KEYS = ArrayHelper.EMPTY_STRING_ARRAY;
|
public static final String[] REGISTRATION_KEYS = ArrayHelper.EMPTY_STRING_ARRAY;
|
||||||
|
|
||||||
private final Type baseType;
|
private final Type valueType;
|
||||||
|
private final AnyDiscriminatorValueStrategy valueStrategy;
|
||||||
private final Map<Object,String> discriminatorValuesToEntityNameMap;
|
private final Map<Object,String> discriminatorValuesToEntityNameMap;
|
||||||
private final Map<String,Object> entityNameToDiscriminatorValueMap;
|
private final Map<String,Object> entityNameToDiscriminatorValueMap;
|
||||||
|
|
||||||
public MetaType(Map<Object,String> discriminatorValuesToEntityNameMap, Type baseType) {
|
public MetaType(
|
||||||
this.baseType = baseType;
|
Type valueType,
|
||||||
this.discriminatorValuesToEntityNameMap = discriminatorValuesToEntityNameMap;
|
AnyDiscriminatorValueStrategy valueStrategy,
|
||||||
this.entityNameToDiscriminatorValueMap = new HashMap<>();
|
Map<Object,String> explicitValueMappings) {
|
||||||
for ( Map.Entry<Object,String> entry : discriminatorValuesToEntityNameMap.entrySet() ) {
|
this.valueType = valueType;
|
||||||
entityNameToDiscriminatorValueMap.put( entry.getValue(), entry.getKey() );
|
|
||||||
|
if ( explicitValueMappings == null || explicitValueMappings.isEmpty() ) {
|
||||||
|
if ( valueStrategy == AnyDiscriminatorValueStrategy.AUTO ) {
|
||||||
|
valueStrategy = AnyDiscriminatorValueStrategy.IMPLICIT;
|
||||||
|
}
|
||||||
|
this.discriminatorValuesToEntityNameMap = new HashMap<>();
|
||||||
|
this.entityNameToDiscriminatorValueMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if ( valueStrategy == AnyDiscriminatorValueStrategy.AUTO ) {
|
||||||
|
valueStrategy = AnyDiscriminatorValueStrategy.EXPLICIT;
|
||||||
|
}
|
||||||
|
this.discriminatorValuesToEntityNameMap = explicitValueMappings;
|
||||||
|
this.entityNameToDiscriminatorValueMap = new HashMap<>();
|
||||||
|
for ( Map.Entry<Object,String> entry : discriminatorValuesToEntityNameMap.entrySet() ) {
|
||||||
|
entityNameToDiscriminatorValueMap.put( entry.getValue(), entry.getKey() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.valueStrategy = valueStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetaType(Map<Object,String> discriminatorValuesToEntityNameMap, Type baseType) {
|
||||||
|
this( baseType, AnyDiscriminatorValueStrategy.AUTO, discriminatorValuesToEntityNameMap );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getBaseType() {
|
public Type getBaseType() {
|
||||||
return baseType;
|
return valueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnyDiscriminatorValueStrategy getValueStrategy() {
|
||||||
|
return valueStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getRegistrationKeys() {
|
public String[] getRegistrationKeys() {
|
||||||
|
@ -60,12 +81,12 @@ public class MetaType extends AbstractType {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getSqlTypeCodes(MappingContext mappingContext) throws MappingException {
|
public int[] getSqlTypeCodes(MappingContext mappingContext) throws MappingException {
|
||||||
return baseType.getSqlTypeCodes( mappingContext );
|
return valueType.getSqlTypeCodes( mappingContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getColumnSpan(MappingContext mapping) throws MappingException {
|
public int getColumnSpan(MappingContext mapping) throws MappingException {
|
||||||
return baseType.getColumnSpan(mapping);
|
return valueType.getColumnSpan(mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -84,7 +105,8 @@ public class MetaType extends AbstractType {
|
||||||
Object value,
|
Object value,
|
||||||
int index,
|
int index,
|
||||||
SharedSessionContractImplementor session) throws HibernateException, SQLException {
|
SharedSessionContractImplementor session) throws HibernateException, SQLException {
|
||||||
baseType.nullSafeSet(st, value==null ? null : entityNameToDiscriminatorValueMap.get(value), index, session);
|
throw new UnsupportedOperationException();
|
||||||
|
// baseType.nullSafeSet(st, value==null ? null : entityNameToDiscriminatorValueMap.get(value), index, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -122,7 +144,7 @@ public class MetaType extends AbstractType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return baseType.getName(); //TODO!
|
return valueType.getName(); //TODO!
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Set;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.hibernate.Filter;
|
import org.hibernate.Filter;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
@ -142,6 +143,11 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getJpaEntityName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableDetails getMappedTableDetails() {
|
public TableDetails getMappedTableDetails() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Map;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
@ -172,6 +173,11 @@ public class PersisterClassProviderTest {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getJpaEntityName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableDetails getMappedTableDetails() {
|
public TableDetails getMappedTableDetails() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|
|
@ -134,6 +134,11 @@ public class CustomPersister implements EntityPersister {
|
||||||
return Custom.class.getName();
|
return Custom.class.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getJpaEntityName() {
|
||||||
|
return Custom.class.getSimpleName();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableDetails getMappedTableDetails() {
|
public TableDetails getMappedTableDetails() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|
Loading…
Reference in New Issue