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.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.type.AnyDiscriminatorValueStrategy;
|
||||
import org.hibernate.type.AnyType;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.MappingContext;
|
||||
|
@ -301,9 +302,13 @@ public class Any extends SimpleValue {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The discriminator {@linkplain Value}
|
||||
*/
|
||||
public static class MetaValue extends SimpleValue {
|
||||
private String typeName;
|
||||
private String columnName;
|
||||
private AnyDiscriminatorValueStrategy valueStrategy;
|
||||
|
||||
private final Consumer<Selectable> selectableConsumer;
|
||||
|
||||
|
@ -396,6 +401,10 @@ public class Any extends SimpleValue {
|
|||
return columnName != null
|
||||
&& getType().getColumnSpan( mappingContext ) == 1;
|
||||
}
|
||||
|
||||
public AnyDiscriminatorValueStrategy getValueStrategy() {
|
||||
return valueStrategy;
|
||||
}
|
||||
}
|
||||
|
||||
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.ManagedBeanRegistry;
|
||||
import org.hibernate.resource.beans.spi.ProvidedInstanceManagedBeanImpl;
|
||||
import org.hibernate.type.AnyDiscriminatorValueStrategy;
|
||||
import org.hibernate.type.AnyType;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.CustomCollectionType;
|
||||
|
@ -123,15 +124,22 @@ public final class MappingHelper {
|
|||
}
|
||||
|
||||
public static AnyType anyMapping(
|
||||
Type metaType,
|
||||
Type discriminatorType,
|
||||
Type identifierType,
|
||||
Map<Object, String> metaValueToEntityNameMap,
|
||||
Map<Object, String> explicitValeMappings,
|
||||
boolean lazy,
|
||||
MetadataBuildingContext buildingContext) {
|
||||
if ( metaValueToEntityNameMap != null ) {
|
||||
metaType = new MetaType( metaValueToEntityNameMap, metaType );
|
||||
return anyMapping( discriminatorType, identifierType, AnyDiscriminatorValueStrategy.AUTO, explicitValeMappings, lazy, buildingContext );
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.cache.MutableCacheKeyBuilder;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.IndexedConsumer;
|
||||
import org.hibernate.metamodel.mapping.DefaultDiscriminatorConverter;
|
||||
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
|
||||
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
|
||||
import org.hibernate.metamodel.mapping.DiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.MappedDiscriminatorConverter;
|
||||
import org.hibernate.metamodel.mapping.MappingType;
|
||||
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
||||
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.basic.BasicFetch;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.type.AnyDiscriminatorValueStrategy;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.descriptor.java.ClassJavaType;
|
||||
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
|
||||
*
|
||||
|
@ -84,6 +84,7 @@ public class AnyDiscriminatorPart implements DiscriminatorMapping, FetchOptions
|
|||
boolean partitioned,
|
||||
BasicType<?> underlyingJdbcMapping,
|
||||
Map<Object,String> valueToEntityNameMap,
|
||||
AnyDiscriminatorValueStrategy valueStrategy,
|
||||
MappingMetamodelImplementor mappingMetamodel) {
|
||||
this.navigableRole = partRole;
|
||||
this.declaringType = declaringType;
|
||||
|
@ -100,20 +101,54 @@ public class AnyDiscriminatorPart implements DiscriminatorMapping, FetchOptions
|
|||
this.partitioned = partitioned;
|
||||
|
||||
this.underlyingJdbcMapping = underlyingJdbcMapping;
|
||||
this.valueConverter = valueToEntityNameMap.isEmpty()
|
||||
? DefaultDiscriminatorConverter.fromMappingMetamodel(
|
||||
this.valueConverter = determineDiscriminatorConverter(
|
||||
partRole,
|
||||
ClassJavaType.INSTANCE,
|
||||
underlyingJdbcMapping,
|
||||
valueToEntityNameMap,
|
||||
valueStrategy,
|
||||
mappingMetamodel
|
||||
)
|
||||
: MappedDiscriminatorConverter.fromValueMappings(
|
||||
);
|
||||
}
|
||||
|
||||
public static DiscriminatorConverter<?, ?> determineDiscriminatorConverter(
|
||||
NavigableRole partRole,
|
||||
BasicType<?> underlyingJdbcMapping,
|
||||
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,
|
||||
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() {
|
||||
|
|
|
@ -89,6 +89,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
|
|||
bootValueMapping.isPartitionKey(),
|
||||
(BasicType<?>) metaType.getBaseType(),
|
||||
metaType.getDiscriminatorValuesToEntityNameMap(),
|
||||
metaType.getValueStrategy(),
|
||||
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;
|
||||
|
||||
/**
|
||||
* Defines the ability to perform post-creation processing for entity mappings.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
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.internal.EntityPersisterConcurrentMap;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
|
||||
|
@ -32,15 +33,18 @@ public class MappingModelCreationProcess {
|
|||
*/
|
||||
public static void process(
|
||||
EntityPersisterConcurrentMap entityPersisterMap,
|
||||
Map<String, CollectionPersister> collectionPersisterMap,
|
||||
RuntimeModelCreationContext creationContext) {
|
||||
final MappingModelCreationProcess process = new MappingModelCreationProcess(
|
||||
entityPersisterMap,
|
||||
collectionPersisterMap,
|
||||
creationContext
|
||||
);
|
||||
process.execute();
|
||||
}
|
||||
|
||||
private final EntityPersisterConcurrentMap entityPersisterMap;
|
||||
private final Map<String, CollectionPersister> collectionPersisterMap;
|
||||
private final RuntimeModelCreationContext creationContext;
|
||||
|
||||
private String currentlyProcessingRole;
|
||||
|
@ -48,8 +52,10 @@ public class MappingModelCreationProcess {
|
|||
|
||||
private MappingModelCreationProcess(
|
||||
EntityPersisterConcurrentMap entityPersisterMap,
|
||||
Map<String, CollectionPersister> collectionPersisterMap,
|
||||
RuntimeModelCreationContext creationContext) {
|
||||
this.entityPersisterMap = entityPersisterMap;
|
||||
this.collectionPersisterMap = collectionPersisterMap;
|
||||
this.creationContext = creationContext;
|
||||
}
|
||||
|
||||
|
@ -83,6 +89,12 @@ public class MappingModelCreationProcess {
|
|||
}
|
||||
}
|
||||
|
||||
for ( CollectionPersister collectionPersister : collectionPersisterMap.values() ) {
|
||||
if ( collectionPersister instanceof InFlightCollectionMapping ) {
|
||||
((InFlightCollectionMapping) collectionPersister).prepareMappingModel( this );
|
||||
}
|
||||
}
|
||||
|
||||
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.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.NavigableRole;
|
||||
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.BasicType;
|
||||
import org.hibernate.type.MetaType;
|
||||
import org.hibernate.type.descriptor.java.ClassJavaType;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hibernate.metamodel.mapping.internal.AnyDiscriminatorPart.determineDiscriminatorConverter;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -42,21 +41,14 @@ public class AnyMappingDomainTypeImpl<T> implements AnyMappingDomainType<T> {
|
|||
final BasicType discriminatorBaseType = (BasicType) discriminatorType.getBaseType();
|
||||
final NavigableRole navigableRole = resolveNavigableRole( bootAnyMapping );
|
||||
|
||||
anyDiscriminatorType = new ConvertedBasicTypeImpl<>(
|
||||
anyDiscriminatorType = new ConvertedBasicTypeImpl(
|
||||
navigableRole.getFullPath(),
|
||||
discriminatorBaseType.getJdbcType(),
|
||||
bootAnyMapping.getMetaValues().isEmpty()
|
||||
? DefaultDiscriminatorConverter.fromMappingMetamodel(
|
||||
determineDiscriminatorConverter(
|
||||
navigableRole,
|
||||
ClassJavaType.INSTANCE,
|
||||
discriminatorBaseType,
|
||||
mappingMetamodel
|
||||
)
|
||||
: MappedDiscriminatorConverter.fromValueMappings(
|
||||
navigableRole,
|
||||
ClassJavaType.INSTANCE,
|
||||
discriminatorBaseType,
|
||||
bootAnyMapping.getMetaValues(),
|
||||
discriminatorType.getValueStrategy(),
|
||||
mappingMetamodel
|
||||
)
|
||||
);
|
||||
|
|
|
@ -195,7 +195,7 @@ public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
|
|||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// after *all* persisters and named queries are registered
|
||||
|
||||
MappingModelCreationProcess.process( entityPersisterMap, context );
|
||||
MappingModelCreationProcess.process( entityPersisterMap, collectionPersisterMap, context );
|
||||
|
||||
for ( EntityPersister persister : entityPersisterMap.values() ) {
|
||||
persister.postInstantiate();
|
||||
|
|
|
@ -4,18 +4,8 @@
|
|||
*/
|
||||
package org.hibernate.persister.collection;
|
||||
|
||||
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.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import jakarta.persistence.metamodel.PluralAttribute;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.Filter;
|
||||
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.CollectionLoader;
|
||||
import org.hibernate.mapping.Any;
|
||||
import org.hibernate.mapping.BasicValue;
|
||||
import org.hibernate.mapping.Collection;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.mapping.Formula;
|
||||
|
@ -72,15 +61,21 @@ import org.hibernate.mapping.Selectable;
|
|||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.metamodel.CollectionClassification;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
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.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
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.EntityCollectionPart;
|
||||
import org.hibernate.metamodel.mapping.internal.InFlightCollectionMapping;
|
||||
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.model.domain.NavigableRole;
|
||||
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.internal.SqlSelectionImpl;
|
||||
import org.hibernate.type.AnyType;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.ComponentType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.EntityType;
|
||||
import org.hibernate.type.MetaType;
|
||||
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.collections.CollectionHelper.arrayList;
|
||||
|
@ -154,7 +159,7 @@ import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER
|
|||
*/
|
||||
@Internal
|
||||
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 CollectionSemantics<?,?> collectionSemantics;
|
||||
|
@ -164,13 +169,13 @@ public abstract class AbstractCollectionPersister
|
|||
protected final String qualifiedTableName;
|
||||
private final CollectionTableMapping tableMapping;
|
||||
|
||||
private final String sqlSelectSizeString;
|
||||
private final String sqlDetectRowByIndexString;
|
||||
private final String sqlDetectRowByElementString;
|
||||
private String sqlSelectSizeString;
|
||||
private String sqlDetectRowByIndexString;
|
||||
private String sqlDetectRowByElementString;
|
||||
|
||||
protected final boolean hasWhere;
|
||||
protected final String sqlWhereString;
|
||||
private final String sqlWhereStringTemplate;
|
||||
protected boolean hasWhere;
|
||||
protected String sqlWhereString;
|
||||
private String sqlWhereStringTemplate;
|
||||
|
||||
private final boolean hasOrder;
|
||||
private final boolean hasManyToManyOrder;
|
||||
|
@ -244,10 +249,14 @@ public abstract class AbstractCollectionPersister
|
|||
private PluralAttributeMapping attributeMapping;
|
||||
private volatile Set<String> affectingFetchProfiles;
|
||||
|
||||
private Collection collectionBootDescriptor;
|
||||
|
||||
public AbstractCollectionPersister(
|
||||
Collection collectionBootDescriptor,
|
||||
@Nullable CollectionDataAccess cacheAccessStrategy,
|
||||
RuntimeModelCreationContext creationContext) throws MappingException, CacheException {
|
||||
this.collectionBootDescriptor = collectionBootDescriptor;
|
||||
|
||||
this.factory = creationContext.getSessionFactory();
|
||||
this.collectionSemantics = creationContext.getBootstrapContext()
|
||||
.getMetadataBuildingOptions()
|
||||
|
@ -295,49 +304,6 @@ public abstract class AbstractCollectionPersister
|
|||
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();
|
||||
|
||||
batchSize = collectionBootDescriptor.getBatchSize() < 0
|
||||
|
@ -512,12 +478,6 @@ public abstract class AbstractCollectionPersister
|
|||
identifierGenerator = null;
|
||||
}
|
||||
|
||||
// GENERATE THE SQL:
|
||||
|
||||
sqlSelectSizeString = generateSelectSizeString( collectionBootDescriptor.isIndexed() && !collectionBootDescriptor.isMap() );
|
||||
sqlDetectRowByIndexString = generateDetectRowByIndexString();
|
||||
sqlDetectRowByElementString = generateDetectRowByElementString();
|
||||
|
||||
isLazy = collectionBootDescriptor.isLazy();
|
||||
isExtraLazy = collectionBootDescriptor.isExtraLazy();
|
||||
|
||||
|
@ -592,6 +552,119 @@ public abstract class AbstractCollectionPersister
|
|||
&& 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) {
|
||||
final Generator generator =
|
||||
collection.getIdentifier()
|
||||
|
|
|
@ -165,7 +165,6 @@ import org.hibernate.metamodel.mapping.EntityVersionMapping;
|
|||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
import org.hibernate.metamodel.mapping.MappedDiscriminatorConverter;
|
||||
import org.hibernate.metamodel.mapping.MappingModelHelper;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
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.EntityVersionMappingImpl;
|
||||
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.ImmutableAttributeMappingList;
|
||||
import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
|
||||
|
@ -337,6 +337,7 @@ public abstract class AbstractEntityPersister
|
|||
private final EntityEntryFactory entityEntryFactory;
|
||||
|
||||
private final String sqlAliasStem;
|
||||
private final String jpaEntityName;
|
||||
|
||||
private SingleIdEntityLoader<?> singleIdLoader;
|
||||
private MultiIdEntityLoader<?> multiIdLoader;
|
||||
|
@ -473,6 +474,7 @@ public abstract class AbstractEntityPersister
|
|||
final EntityDataAccess cacheAccessStrategy,
|
||||
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
|
||||
final RuntimeModelCreationContext creationContext) throws HibernateException {
|
||||
this.jpaEntityName = persistentClass.getJpaEntityName();
|
||||
|
||||
//set it here, but don't call it, since it's still uninitialized!
|
||||
factory = creationContext.getSessionFactory();
|
||||
|
@ -2279,10 +2281,10 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
//noinspection rawtypes
|
||||
final DiscriminatorConverter converter = MappedDiscriminatorConverter.fromValueMappings(
|
||||
final DiscriminatorConverter converter = new ExplicitDiscriminatorConverter(
|
||||
getNavigableRole().append( EntityDiscriminatorMapping.DISCRIMINATOR_ROLE_NAME ),
|
||||
domainJavaType,
|
||||
underlingJdbcMapping,
|
||||
underlingJdbcMapping.getRelationalJavaType(),
|
||||
getSubclassByDiscriminatorValue(),
|
||||
factory.getMappingMetamodel()
|
||||
);
|
||||
|
@ -3776,6 +3778,11 @@ public abstract class AbstractEntityPersister
|
|||
return entityMetamodel.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getJpaEntityName() {
|
||||
return jpaEntityName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInherited() {
|
||||
return entityMetamodel.isInherited();
|
||||
|
|
|
@ -10,6 +10,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.LockMode;
|
||||
|
@ -37,6 +39,7 @@ import org.hibernate.generator.values.GeneratedValues;
|
|||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.internal.FilterAliasGenerator;
|
||||
import org.hibernate.internal.TableGroupFilterAliasGenerator;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.loader.ast.spi.MultiIdLoadOptions;
|
||||
import org.hibernate.loader.ast.spi.MultiNaturalIdLoader;
|
||||
import org.hibernate.loader.ast.spi.NaturalIdLoader;
|
||||
|
@ -178,6 +181,16 @@ public interface EntityPersister extends EntityMappingType, EntityMutationTarget
|
|||
*/
|
||||
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
|
||||
* 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 {
|
||||
private final TypeConfiguration typeConfiguration;
|
||||
private final Type identifierType;
|
||||
private final Type discriminatorType;
|
||||
private final MetaType discriminatorType;
|
||||
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.discriminatorType = discriminatorType;
|
||||
this.identifierType = identifierType;
|
||||
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() {
|
||||
return identifierType;
|
||||
}
|
||||
|
|
|
@ -4,47 +4,68 @@
|
|||
*/
|
||||
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.Internal;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
|
||||
import org.hibernate.persister.entity.DiscriminatorMetadata;
|
||||
import org.hibernate.persister.entity.DiscriminatorType;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @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 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<String,Object> entityNameToDiscriminatorValueMap;
|
||||
|
||||
public MetaType(Map<Object,String> discriminatorValuesToEntityNameMap, Type baseType) {
|
||||
this.baseType = baseType;
|
||||
this.discriminatorValuesToEntityNameMap = discriminatorValuesToEntityNameMap;
|
||||
public MetaType(
|
||||
Type valueType,
|
||||
AnyDiscriminatorValueStrategy valueStrategy,
|
||||
Map<Object,String> explicitValueMappings) {
|
||||
this.valueType = valueType;
|
||||
|
||||
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() {
|
||||
return baseType;
|
||||
return valueType;
|
||||
}
|
||||
|
||||
public AnyDiscriminatorValueStrategy getValueStrategy() {
|
||||
return valueStrategy;
|
||||
}
|
||||
|
||||
public String[] getRegistrationKeys() {
|
||||
|
@ -60,12 +81,12 @@ public class MetaType extends AbstractType {
|
|||
}
|
||||
|
||||
public int[] getSqlTypeCodes(MappingContext mappingContext) throws MappingException {
|
||||
return baseType.getSqlTypeCodes( mappingContext );
|
||||
return valueType.getSqlTypeCodes( mappingContext );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnSpan(MappingContext mapping) throws MappingException {
|
||||
return baseType.getColumnSpan(mapping);
|
||||
return valueType.getColumnSpan(mapping);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -84,7 +105,8 @@ public class MetaType extends AbstractType {
|
|||
Object value,
|
||||
int index,
|
||||
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
|
||||
|
@ -122,7 +144,7 @@ public class MetaType extends AbstractType {
|
|||
|
||||
@Override
|
||||
public String getName() {
|
||||
return baseType.getName(); //TODO!
|
||||
return valueType.getName(); //TODO!
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Set;
|
|||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.Filter;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
|
@ -142,6 +143,11 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getJpaEntityName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDetails getMappedTableDetails() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Map;
|
|||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
|
@ -172,6 +173,11 @@ public class PersisterClassProviderTest {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getJpaEntityName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDetails getMappedTableDetails() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -134,6 +134,11 @@ public class CustomPersister implements EntityPersister {
|
|||
return Custom.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getJpaEntityName() {
|
||||
return Custom.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDetails getMappedTableDetails() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
Loading…
Reference in New Issue