HHH-16339 - Unify entity and any discriminator handling

This commit is contained in:
Steve Ebersole 2023-03-21 14:46:49 -05:00
parent 055aeba6b9
commit 0455e2d676
39 changed files with 845 additions and 558 deletions

View File

@ -15,6 +15,7 @@ import org.hibernate.AssertionFailure;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.internal.EntityManagerMessageLogger;
import org.hibernate.internal.HEMLogging;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.List;
@ -245,10 +246,12 @@ public class AttributeFactory {
.getJavaTypeRegistry()
.resolveDescriptor( anyType.getReturnedClass() );
return (DomainType<Y>) new AnyMappingDomainTypeImpl(
(Any) typeContext.getHibernateValue(),
anyType,
(JavaType<Class>) baseJtd,
context.getTypeConfiguration(),
context.getMetamodel()
context.getMetamodel(),
context.getRuntimeModelCreationContext().getSessionFactory()
);
}
case EMBEDDABLE: {

View File

@ -16,6 +16,8 @@ import org.hibernate.sql.ast.tree.predicate.Predicate;
* Things that have a discriminator associated with it.
*/
public interface Discriminatable {
DiscriminatorMapping getDiscriminatorMapping();
/**
* Apply the discriminator as a predicate via the {@code predicateConsumer}
*/

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.metamodel.mapping;
import org.hibernate.metamodel.mapping.internal.AnyDiscriminatorPart;
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.results.graph.Fetchable;
@ -21,8 +22,15 @@ import org.hibernate.sql.results.graph.FetchableContainer;
*
* @author Steve Ebersole
*/
public interface DiscriminatedAssociationModelPart extends Fetchable, FetchableContainer, TableGroupJoinProducer {
BasicValuedModelPart getDiscriminatorPart();
public interface DiscriminatedAssociationModelPart extends Discriminatable, Fetchable, FetchableContainer, TableGroupJoinProducer {
/**
* @deprecated Use {@link #getDiscriminatorMapping} instead.
*/
@Deprecated( since = "6.2", forRemoval = true )
default BasicValuedModelPart getDiscriminatorPart() {
return getDiscriminatorMapping();
}
BasicValuedModelPart getKeyPart();
EntityMappingType resolveDiscriminatorValue(Object discriminatorValue);

View File

@ -0,0 +1,183 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.metamodel.mapping;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.RepresentationMode;
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.converter.spi.BasicValueConverter;
import org.hibernate.type.descriptor.java.JavaType;
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 DiscriminatorConverter<O,R> implements BasicValueConverter<O,R> {
public static <O,R> DiscriminatorConverter<O,R> fromValueMappings(
NavigableRole role,
JavaType<O> domainJavaType,
BasicType<R> underlyingJdbcMapping,
Map<Object,String> valueMappings,
SessionFactoryImplementor sessionFactory) {
final MappingMetamodelImplementor mappingMetamodel = sessionFactory.getMappingMetamodel();
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 DiscriminatorConverter<>(
role,
domainJavaType,
underlyingJdbcMapping.getJavaTypeDescriptor(),
valueDetailsList
);
}
private final NavigableRole discriminatorRole;
private final JavaType<O> domainJavaType;
private final JavaType<R> relationalJavaType;
private final Map<Object, DiscriminatorValueDetails> discriminatorValueToEntityNameMap;
private final Map<String,DiscriminatorValueDetails> entityNameToDiscriminatorValueMap;
public DiscriminatorConverter(
NavigableRole discriminatorRole,
JavaType<O> domainJavaType,
JavaType<R> relationalJavaType,
List<DiscriminatorValueDetails> valueMappings) {
this.discriminatorRole = discriminatorRole;
this.domainJavaType = domainJavaType;
this.relationalJavaType = 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 );
} );
}
public NavigableRole getNavigableRole() {
return discriminatorRole;
}
@Override
public JavaType<O> getDomainJavaType() {
return domainJavaType;
}
@Override
public JavaType<R> getRelationalJavaType() {
return relationalJavaType;
}
public DiscriminatorValueDetails getDetailsForRelationalForm(R relationalForm) {
return getDetailsForDiscriminatorValue( relationalForm );
}
@Override
public O toDomainValue(R relationalForm) {
assert relationalForm == null || relationalJavaType.isInstance( relationalForm );
final DiscriminatorValueDetails matchingValueDetails = getDetailsForRelationalForm( relationalForm );
if ( matchingValueDetails == null ) {
throw new IllegalStateException( "Could not resolve discriminator value" );
}
final EntityMappingType indicatedEntity = matchingValueDetails.getIndicatedEntity();
//noinspection unchecked
return indicatedEntity.getRepresentationStrategy().getMode() == RepresentationMode.POJO
&& indicatedEntity.getEntityName().equals( indicatedEntity.getJavaType().getJavaTypeClass().getName() )
? (O) indicatedEntity.getJavaType().getJavaTypeClass()
: (O) indicatedEntity.getEntityName();
}
public DiscriminatorValueDetails getDetailsForEntityName(String entityName) {
return entityNameToDiscriminatorValueMap.get( entityName );
}
public DiscriminatorValueDetails getDetailsForDiscriminatorValue(Object value) {
if ( value == null ) {
return discriminatorValueToEntityNameMap.get( NULL_DISCRIMINATOR );
}
final DiscriminatorValueDetails valueMatch = discriminatorValueToEntityNameMap.get( value );
if ( valueMatch != null ) {
return valueMatch;
}
return discriminatorValueToEntityNameMap.get( NOT_NULL_DISCRIMINATOR );
}
@Override
public R toRelationalValue(O domainForm) {
assert domainForm == null || domainForm instanceof String || domainForm instanceof Class;
if ( domainForm == null ) {
return null;
}
final String entityName;
if ( domainForm instanceof Class ) {
entityName = ( (Class<?>) domainForm ).getName();
}
else {
entityName = (String) domainForm;
}
final DiscriminatorValueDetails discriminatorValueDetails = getDetailsForEntityName( entityName );
//noinspection unchecked
return (R) discriminatorValueDetails.getValue();
}
@Override
public String toString() {
return "DiscriminatorConverter(" + discriminatorRole.getFullPath() + ")";
}
public void forEachValueDetail(Consumer<DiscriminatorValueDetails> consumer) {
discriminatorValueToEntityNameMap.forEach( (value, detail) -> consumer.accept( detail ) );
}
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;
}
}

View File

@ -0,0 +1,62 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.metamodel.mapping;
import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.type.descriptor.java.JavaType;
/**
* Mapping of a discriminator, for either {@linkplain EntityMappingType#getDiscriminatorMapping() entity} or
* {@linkplain DiscriminatedAssociationModelPart#getDiscriminatorMapping() association} (ANY) discrimination.
* <p/>
* Represents a composition of <ul>
* <li>a {@linkplain #getValueConverter() converter} between the domain and relational form</li>
* <li>a {@linkplain #getUnderlyingJdbcMapping JDBC mapping} to read and write the relational values</li>
* </ul>
*
* @author Steve Ebersole
*/
public interface DiscriminatorMapping extends VirtualModelPart, BasicValuedModelPart, Fetchable {
/**
* Information about the value mappings
*/
DiscriminatorConverter<?,?> getValueConverter();
JdbcMapping getUnderlyingJdbcMapping();
/**
* The domain Java form, which is either {@code JavaType<Class>} (entity class)
* or {@code JavaType<String>} (entity name).
*/
default JavaType<?> getDomainJavaType() {
return getValueConverter().getDomainJavaType();
}
/**
* The relational Java form. This will typically be some form of integer
* or character value.
*/
default JavaType<?> getRelationalJavaType() {
return getValueConverter().getRelationalJavaType();
}
/**
* Create the appropriate SQL expression for this discriminator
*
* @param jdbcMappingToUse The JDBC mapping to use. This allows opting between
* the "domain result type" (aka Class) and the "underlying type" (Integer, String, etc)
*/
Expression resolveSqlExpression(
NavigablePath navigablePath,
JdbcMapping jdbcMappingToUse,
TableGroup tableGroup,
SqlAstCreationState creationState);
}

View File

@ -0,0 +1,33 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.metamodel.mapping;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.type.BasicType;
import org.hibernate.type.ConvertedBasicType;
import org.hibernate.type.descriptor.java.JavaType;
/**
* Union of {@link ConvertedBasicType} and {@link BasicDomainType} capabilities.
*
* @implNote We need the {@link BasicDomainType} aspect for handling in SQM trees.
*
* @param <O> The Java type of the domain form of the discriminator.
*
* @author Steve Ebersole
*/
public interface DiscriminatorType<O> extends ConvertedBasicType<O>, BasicDomainType<O> {
@Override
DiscriminatorConverter<O, ?> getValueConverter();
BasicType<?> getUnderlyingJdbcMapping();
@Override
default JavaType<O> getJavaTypeDescriptor() {
return ConvertedBasicType.super.getJavaTypeDescriptor();
}
}

View File

@ -0,0 +1,37 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.metamodel.mapping;
/**
* Details for a particular discriminator value.
*
* @apiNote For {@linkplain jakarta.persistence.InheritanceType#JOINED joined} and
* {@linkplain jakarta.persistence.InheritanceType#TABLE_PER_CLASS union} inheritance,
* the discriminator also effectively indicates a specific table. That table can be
* found via {@linkplain EntityMappingType#getMappedTableDetails()} for the
* {@linkplain #getIndicatedEntity() indicated entity}
*
* @see jakarta.persistence.DiscriminatorValue
*/
public interface DiscriminatorValueDetails {
/**
* The discriminator value
*/
Object getValue();
/**
* The name of the concrete entity-type mapped to this {@linkplain #getValue() discriminator value}
*/
default String getIndicatedEntityName() {
return getIndicatedEntity().getEntityName();
}
/**
* Form of {@link #getIndicatedEntityName()} returning the matched {@link EntityMappingType}
*/
EntityMappingType getIndicatedEntity();
}

View File

@ -28,7 +28,7 @@ import org.hibernate.sql.results.graph.basic.BasicFetch;
*
* @author Steve Ebersole
*/
public interface EntityDiscriminatorMapping extends VirtualModelPart, BasicValuedModelPart, FetchOptions {
public interface EntityDiscriminatorMapping extends DiscriminatorMapping, FetchOptions {
String ROLE_NAME = "{discriminator}";
String LEGACY_HQL_ROLE_NAME = "class";
@ -63,35 +63,6 @@ public interface EntityDiscriminatorMapping extends VirtualModelPart, BasicValue
*/
DiscriminatorValueDetails resolveDiscriminatorValue(Object value);
/**
* Details for a particular discriminator value.
*
* @apiNote For {@linkplain jakarta.persistence.InheritanceType#JOINED joined}
* {@linkplain jakarta.persistence.InheritanceType#TABLE_PER_CLASS union} inheritance,
* the discriminator also effectively indicates a specific table. That table can be
* found via {@linkplain EntityMappingType#getMappedTableDetails()} for the
* {@linkplain #getIndicatedEntity() indicated entity}
*
* @see jakarta.persistence.DiscriminatorValue
*/
interface DiscriminatorValueDetails {
/**
* The discriminator value
*/
Object getValue();
/**
* The SQL literal representation of the discriminator value. E.g.
* for Strings, this would be the fully SQL-quoted form.
*/
Object getSqlLiteralValue();
/**
* The concrete entity-type mapped to this discriminator value
*/
EntityMappingType getIndicatedEntity();
}
/**
* Create the appropriate SQL expression for this discriminator
*

View File

@ -6,19 +6,20 @@
*/
package org.hibernate.metamodel.mapping.internal;
import java.util.Map;
import java.util.function.BiConsumer;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.IndexedConsumer;
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
import org.hibernate.metamodel.mapping.DiscriminatorType;
import org.hibernate.metamodel.mapping.DiscriminatorValueDetails;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.mapping.SelectableConsumer;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.entity.DiscriminatorType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
@ -32,9 +33,6 @@ import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType;
import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR;
import static org.hibernate.persister.entity.DiscriminatorHelper.NULL_DISCRIMINATOR;
/**
* @implNote `discriminatorType` represents the mapping to Class, whereas `discriminatorType.getUnderlyingType()`
* represents the "raw" JDBC mapping (String, Integer, etc)
@ -44,34 +42,34 @@ import static org.hibernate.persister.entity.DiscriminatorHelper.NULL_DISCRIMINA
public abstract class AbstractDiscriminatorMapping implements EntityDiscriminatorMapping {
private final NavigableRole role;
private final JdbcMapping jdbcMapping;
private final EntityMappingType entityDescriptor;
private final Map<Object, DiscriminatorValueDetails> valueMappings;
private final BasicType<Object> underlyingJdbcMapping;
private final DiscriminatorType<Object> discriminatorType;
private final EntityMappingType entityDescriptor;
public AbstractDiscriminatorMapping(
EntityMappingType entityDescriptor,
DiscriminatorType<?> discriminatorType,
Map<Object, DiscriminatorValueDetails> valueMappings,
MappingModelCreationProcess creationProcess) {
this.jdbcMapping = discriminatorType.getUnderlyingType().getJdbcMapping();
DiscriminatorType<Object> discriminatorType,
BasicType<Object> underlyingJdbcMapping) {
this.underlyingJdbcMapping = underlyingJdbcMapping;
this.entityDescriptor = entityDescriptor;
this.valueMappings = valueMappings;
this.role = entityDescriptor.getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME );
//noinspection unchecked
this.discriminatorType = (DiscriminatorType<Object>) discriminatorType;
this.discriminatorType = discriminatorType;
}
public EntityMappingType getEntityDescriptor() {
return entityDescriptor;
}
public BasicType<?> getUnderlyingJdbcMappingType() {
return discriminatorType.getUnderlyingType();
@Override
public BasicType<?> getUnderlyingJdbcMapping() {
return discriminatorType.getUnderlyingJdbcMapping();
}
@Override
public DiscriminatorConverter<?, ?> getValueConverter() {
return discriminatorType.getValueConverter();
}
@ -90,16 +88,7 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
@Override
public DiscriminatorValueDetails resolveDiscriminatorValue(Object value) {
if ( value == null ) {
return valueMappings.get( NULL_DISCRIMINATOR );
}
final DiscriminatorValueDetails matchedType = valueMappings.get( value );
if ( matchedType != null ) {
return matchedType;
}
return valueMappings.get( NOT_NULL_DISCRIMINATOR );
return discriminatorType.getValueConverter().getDetailsForDiscriminatorValue( value );
}
@Override
@ -127,7 +116,7 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
// create a SqlSelection based on the underlying JdbcMapping
final SqlSelection sqlSelection = resolveSqlSelection(
navigablePath,
jdbcMapping,
underlyingJdbcMapping,
tableGroup,
null,
creationState.getSqlAstCreationState()
@ -176,7 +165,7 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
// create a SqlSelection based on the underlying JdbcMapping
final SqlSelection sqlSelection = resolveSqlSelection(
fetchablePath,
jdbcMapping,
underlyingJdbcMapping,
tableGroup,
fetchParent,
creationState.getSqlAstCreationState()
@ -201,7 +190,7 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
DomainResultCreationState creationState) {
resolveSqlSelection(
navigablePath,
jdbcMapping,
underlyingJdbcMapping,
tableGroup,
null,
creationState.getSqlAstCreationState()
@ -215,7 +204,7 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
DomainResultCreationState creationState,
BiConsumer<SqlSelection, JdbcMapping> selectionConsumer) {
selectionConsumer.accept(
resolveSqlSelection( navigablePath, jdbcMapping, tableGroup, null, creationState.getSqlAstCreationState() ),
resolveSqlSelection( navigablePath, underlyingJdbcMapping, tableGroup, null, creationState.getSqlAstCreationState() ),
getJdbcMapping()
);
}
@ -228,13 +217,13 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
Y y,
JdbcValuesBiConsumer<X, Y> valuesConsumer,
SharedSessionContractImplementor session) {
valuesConsumer.consume( offset, x, y, value, jdbcMapping );
valuesConsumer.consume( offset, x, y, value, underlyingJdbcMapping );
return getJdbcTypeCount();
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
action.accept( offset, jdbcMapping );
action.accept( offset, underlyingJdbcMapping );
return getJdbcTypeCount();
}

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.metamodel.mapping.internal;
import java.util.Map;
import java.util.function.BiConsumer;
import org.hibernate.cache.MutableCacheKeyBuilder;
@ -14,14 +15,14 @@ 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.BasicValuedModelPart;
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.MappingType;
import org.hibernate.metamodel.mapping.SelectableConsumer;
import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.spi.FromClauseAccess;
@ -37,7 +38,8 @@ import org.hibernate.sql.results.graph.Fetch;
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.type.MetaType;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.ClassJavaType;
import org.hibernate.type.descriptor.java.JavaType;
/**
@ -45,7 +47,7 @@ import org.hibernate.type.descriptor.java.JavaType;
*
* @author Steve Ebersole
*/
public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions, SelectableMapping {
public class AnyDiscriminatorPart implements DiscriminatorMapping, FetchOptions {
public static final String ROLE_NAME = EntityDiscriminatorMapping.ROLE_NAME;
private final NavigableRole navigableRole;
@ -61,7 +63,9 @@ public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions,
private final boolean insertable;
private final boolean updateable;
private final boolean partitioned;
private final MetaType metaType;
private final BasicType<?> underlyingJdbcMapping;
private final DiscriminatorConverter<?,?> valueConverter;
public AnyDiscriminatorPart(
NavigableRole partRole,
@ -75,7 +79,9 @@ public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions,
boolean insertable,
boolean updateable,
boolean partitioned,
MetaType metaType) {
BasicType<?> underlyingJdbcMapping,
Map<Object,String> valueToEntityNameMap,
SessionFactoryImplementor sessionFactory) {
this.navigableRole = partRole;
this.declaringType = declaringType;
this.table = table;
@ -87,15 +93,23 @@ public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions,
this.insertable = insertable;
this.updateable = updateable;
this.partitioned = partitioned;
this.metaType = metaType;
this.underlyingJdbcMapping = underlyingJdbcMapping;
this.valueConverter = DiscriminatorConverter.fromValueMappings(
partRole,
ClassJavaType.INSTANCE,
underlyingJdbcMapping,
valueToEntityNameMap,
sessionFactory
);
}
public MetaType getMetaType() {
return metaType;
public DiscriminatorConverter<?,?> getValueConverter() {
return valueConverter;
}
public JdbcMapping jdbcMapping() {
return (JdbcMapping) metaType.getBaseType();
return underlyingJdbcMapping;
}
@Override
@ -184,38 +198,19 @@ public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions,
}
@Override
public <T> DomainResult<T> createDomainResult(
NavigablePath navigablePath,
TableGroup tableGroup,
String resultVariable,
DomainResultCreationState creationState) {
throw new UnsupportedOperationException();
}
@Override
public void applySqlSelections(
NavigablePath navigablePath, TableGroup tableGroup, DomainResultCreationState creationState) {
throw new UnsupportedOperationException();
}
@Override
public void applySqlSelections(
NavigablePath navigablePath,
TableGroup tableGroup,
DomainResultCreationState creationState,
BiConsumer<SqlSelection, JdbcMapping> selectionConsumer) {
throw new UnsupportedOperationException();
public JdbcMapping getUnderlyingJdbcMapping() {
return underlyingJdbcMapping;
}
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
return metaType.disassemble( value, session, value );
return underlyingJdbcMapping.disassemble( value, session, value );
}
@Override
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
cacheKey.addValue( metaType.disassemble( value, session, value ) );
cacheKey.addHashCode( metaType.getHashCode( value ) );
cacheKey.addValue( underlyingJdbcMapping.disassemble( value, session, value ) );
cacheKey.addHashCode( underlyingJdbcMapping.getHashCode( value ) );
}
@Override
@ -328,4 +323,46 @@ public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions,
public FetchTiming getTiming() {
return FetchTiming.IMMEDIATE;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// NOTE : the following are "unsupported" because handling for any-mapping
// discriminators into SQL AST is handled by outside code. Consolidate
// with `EntityDiscriminatorMapping` to use these contracts for any-mapping
// discriminators as well.
@Override
public <T> DomainResult<T> createDomainResult(
NavigablePath navigablePath,
TableGroup tableGroup,
String resultVariable,
DomainResultCreationState creationState) {
throw new UnsupportedOperationException();
}
@Override
public Expression resolveSqlExpression(
NavigablePath navigablePath,
JdbcMapping jdbcMappingToUse,
TableGroup tableGroup,
SqlAstCreationState creationState) {
throw new UnsupportedOperationException();
}
@Override
public void applySqlSelections(
NavigablePath navigablePath,
TableGroup tableGroup,
DomainResultCreationState creationState) {
throw new UnsupportedOperationException();
}
@Override
public void applySqlSelections(
NavigablePath navigablePath,
TableGroup tableGroup,
DomainResultCreationState creationState,
BiConsumer<SqlSelection, JdbcMapping> selectionConsumer) {
throw new UnsupportedOperationException();
}
}

View File

@ -11,9 +11,9 @@ import java.util.Map;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.DiscriminatorType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
import org.hibernate.persister.entity.DiscriminatorType;
import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.SqlAstTranslator;
@ -32,6 +32,7 @@ import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.type.BasicType;
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
@ -49,16 +50,14 @@ public class CaseStatementDiscriminatorMappingImpl extends AbstractDiscriminator
String[] notNullColumnNames,
String[] discriminatorValues,
boolean[] discriminatorAbstract,
Map<String,String> subEntityNameByTableName,
DiscriminatorType<?> incomingDiscriminatorType,
Map<Object, DiscriminatorValueDetails> valueMappings,
MappingModelCreationProcess creationProcess) {
super( entityDescriptor, incomingDiscriminatorType, valueMappings, creationProcess );
//noinspection unchecked
super( entityDescriptor, (DiscriminatorType<Object>) incomingDiscriminatorType, (BasicType<Object>) incomingDiscriminatorType.getUnderlyingJdbcMapping() );
for ( int i = 0; i < discriminatorValues.length; i++ ) {
if ( !discriminatorAbstract[i] ) {
final String tableName = tableNames[notNullColumnTableNumbers[i]];
final String subEntityName = subEntityNameByTableName.get( tableName );
final String oneSubEntityColumn = notNullColumnNames[i];
final String discriminatorValue = discriminatorValues[i];
tableDiscriminatorDetailsMap.put(
@ -66,9 +65,7 @@ public class CaseStatementDiscriminatorMappingImpl extends AbstractDiscriminator
new TableDiscriminatorDetails(
tableName,
oneSubEntityColumn,
getUnderlyingJdbcMappingType().getJavaTypeDescriptor()
.wrap( discriminatorValue, null ),
subEntityName
getUnderlyingJdbcMapping().getJavaTypeDescriptor().wrap( discriminatorValue, null )
)
);
}
@ -202,30 +199,28 @@ public class CaseStatementDiscriminatorMappingImpl extends AbstractDiscriminator
private final String tableName;
private final String checkColumnName;
private final Object discriminatorValue;
private final String subclassEntityName;
public TableDiscriminatorDetails(String tableName, String checkColumnName, Object discriminatorValue, String subclassEntityName) {
public TableDiscriminatorDetails(
String tableName,
String checkColumnName,
Object discriminatorValue) {
this.tableName = tableName;
this.checkColumnName = checkColumnName;
this.discriminatorValue = discriminatorValue;
this.subclassEntityName = subclassEntityName;
}
String getTableExpression() {
return tableName;
}
Object getDiscriminatorValue() {
return discriminatorValue;
}
String getSubclassEntityName() {
return subclassEntityName;
}
String getCheckColumnName() {
return checkColumnName;
}
@Override
public String toString() {
return "TableDiscriminatorDetails(`" + tableName + "." + checkColumnName + "` = " + discriminatorValue + ")";
}
}
public final class CaseStatementDiscriminatorExpression implements SelfRenderingExpression {
@ -273,7 +268,7 @@ public class CaseStatementDiscriminatorMappingImpl extends AbstractDiscriminator
predicate,
new QueryLiteral<>(
tableDiscriminatorDetails.getDiscriminatorValue(),
getUnderlyingJdbcMappingType()
getUnderlyingJdbcMapping()
)
);
}

View File

@ -23,6 +23,7 @@ import org.hibernate.mapping.Property;
import org.hibernate.metamodel.mapping.AttributeMetadata;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.DiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
@ -102,7 +103,7 @@ public class DiscriminatedAssociationAttributeMapping
}
@Override
public BasicValuedModelPart getDiscriminatorPart() {
public DiscriminatorMapping getDiscriminatorMapping() {
return discriminatorMapping.getDiscriminatorPart();
}
@ -501,4 +502,9 @@ public class DiscriminatedAssociationAttributeMapping
public String getSqlAliasStem() {
return getAttributeName();
}
@Override
public void applyDiscriminator(Consumer<Predicate> predicateConsumer, String alias, TableGroup tableGroup, SqlAstCreationState creationState) {
throw new UnsupportedOperationException();
}
}

View File

@ -7,11 +7,8 @@
package org.hibernate.metamodel.mapping.internal;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.FetchStyle;
@ -21,9 +18,10 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Selectable;
import org.hibernate.metamodel.RuntimeMetamodels;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.DiscriminatorMapping;
import org.hibernate.metamodel.mapping.DiscriminatorValueDetails;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.MappingType;
@ -83,6 +81,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
final Column metaColumn = (Column) metaSelectable;
final Column keyColumn = (Column) keySelectable;
final MetaType metaType = (MetaType) anyType.getDiscriminatorType();
final AnyDiscriminatorPart discriminatorPart = new AnyDiscriminatorPart(
containerRole.append( AnyDiscriminatorPart.ROLE_NAME),
declaringModelPart,
@ -95,7 +94,9 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
bootValueMapping.isColumnInsertable( 0 ),
bootValueMapping.isColumnUpdateable( 0 ),
bootValueMapping.isPartitionKey(),
(MetaType) anyType.getDiscriminatorType()
(BasicType<?>) metaType.getBaseType(),
metaType.getDiscriminatorValuesToEntityNameMap(),
creationProcess.getCreationContext().getSessionFactory()
);
@ -124,7 +125,6 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
bootValueMapping.isLazy()
? FetchTiming.DELAYED
: FetchTiming.IMMEDIATE,
bootValueMapping.getMetaValues(),
creationProcess.getCreationContext().getSessionFactory()
);
}
@ -136,25 +136,12 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
private final FetchTiming fetchTiming;
private final SessionFactoryImplementor sessionFactory;
private static class ValueMapping {
private final Object discriminatorValue;
private final EntityMappingType entityMapping;
public ValueMapping(Object discriminatorValue, EntityMappingType entityMapping) {
this.discriminatorValue = discriminatorValue;
this.entityMapping = entityMapping;
}
}
private final LinkedList<ValueMapping> discriminatorValueMappings = new LinkedList<>();
public DiscriminatedAssociationMapping(
DiscriminatedAssociationModelPart modelPart,
AnyDiscriminatorPart discriminatorPart,
BasicValuedModelPart keyPart,
JavaType<?> baseAssociationJtd,
FetchTiming fetchTiming,
Map<Object,String> discriminatorValueMappings,
SessionFactoryImplementor sessionFactory) {
this.modelPart = modelPart;
this.discriminatorPart = discriminatorPart;
@ -162,20 +149,13 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
this.baseAssociationJtd = baseAssociationJtd;
this.fetchTiming = fetchTiming;
this.sessionFactory = sessionFactory;
final RuntimeMetamodels runtimeMetamodels = sessionFactory.getRuntimeMetamodels();
discriminatorValueMappings.forEach(
(value, entityName) -> this.discriminatorValueMappings.add(
new ValueMapping( value, runtimeMetamodels.getEntityMappingType( entityName ) )
)
);
}
public DiscriminatedAssociationModelPart getModelPart() {
return modelPart;
}
public BasicValuedModelPart getDiscriminatorPart() {
public DiscriminatorMapping getDiscriminatorPart() {
return discriminatorPart;
}
@ -184,26 +164,17 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
}
public Object resolveDiscriminatorValueToEntityMapping(EntityMappingType entityMappingType) {
for ( int i = 0; i < discriminatorValueMappings.size(); i++ ) {
final ValueMapping valueMapping = discriminatorValueMappings.get( i );
if ( valueMapping.entityMapping.equals( entityMappingType ) ) {
return valueMapping.discriminatorValue;
}
}
return null;
final DiscriminatorValueDetails details = discriminatorPart.getValueConverter().getDetailsForEntityName( entityMappingType.getEntityName() );
return details != null
? details.getValue()
: null;
}
public EntityMappingType resolveDiscriminatorValueToEntityMapping(Object discriminatorValue) {
//noinspection ForLoopReplaceableByForEach
for ( int i = 0; i < discriminatorValueMappings.size(); i++ ) {
final ValueMapping valueMapping = discriminatorValueMappings.get( i );
if ( valueMapping.discriminatorValue.equals( discriminatorValue ) ) {
return valueMapping.entityMapping;
}
}
return null;
final DiscriminatorValueDetails details = discriminatorPart.getValueConverter().getDetailsForDiscriminatorValue( discriminatorValue );
return details != null
? details.getIndicatedEntity()
: null;
}
public <X, Y> int breakDownJdbcValues(
@ -270,31 +241,6 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
.getEntityMappingType( entityName );
}
public void forEachConcreteType(Consumer<EntityMappingType> consumer) {
discriminatorValueMappings.forEach( valueMapping -> consumer.accept( valueMapping.entityMapping ) );
}
public EntityMappingType findConcrete(Function<EntityMappingType, EntityMappingType> matcher) {
for ( ValueMapping discriminatorValueMapping : discriminatorValueMappings ) {
final EntityMappingType matched = matcher.apply( discriminatorValueMapping.entityMapping );
if ( matched != null ) {
return matched;
}
}
return null;
}
public <T> T fromConcrete(Function<EntityMappingType,T> matcher) {
for ( ValueMapping discriminatorValueMapping : discriminatorValueMappings ) {
final T matched = matcher.apply( discriminatorValueMapping.entityMapping );
if ( matched != null ) {
return matched;
}
}
return null;
}
public ModelPart findSubPart(String name, EntityMappingType treatTarget) {
if ( AnyDiscriminatorPart.ROLE_NAME.equals( name ) ) {
return getDiscriminatorPart();
@ -311,20 +257,18 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
return resolveAssociatedSubPart( name, treatTarget );
}
for ( ValueMapping discriminatorValueMapping : discriminatorValueMappings ) {
return discriminatorPart.getValueConverter().fromValueDetails( (detail) -> {
try {
final ModelPart subPart = resolveAssociatedSubPart( name, discriminatorValueMapping.entityMapping );
final ModelPart subPart = resolveAssociatedSubPart( name, detail.getIndicatedEntity() );
if ( subPart != null ) {
return subPart;
}
}
catch (Exception e) {
//noinspection UnnecessaryContinue
continue;
catch (Exception ignore) {
}
}
return null;
return null;
} );
}
private ModelPart resolveAssociatedSubPart(String name, EntityMappingType entityMapping) {
@ -347,10 +291,9 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
private void ensureMapped(EntityMappingType treatTarget) {
assert treatTarget != null;
for ( ValueMapping mapping : discriminatorValueMappings ) {
if ( mapping.entityMapping.equals( treatTarget ) ) {
return;
}
final DiscriminatorValueDetails details = discriminatorPart.getValueConverter().getDetailsForEntityName( treatTarget.getEntityName() );
if ( details != null ) {
return;
}
throw new IllegalArgumentException(
@ -619,6 +562,8 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
public T assemble(
RowProcessingState rowProcessingState,
JdbcValuesSourceProcessingOptions options) {
// resolve the key and the discriminator, and then use those to load the indicated entity
final Object discriminatorValue = discriminatorValueAssembler.assemble( rowProcessingState, options );
if ( discriminatorValue == null ) {
@ -631,12 +576,8 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
final Object keyValue = keyValueAssembler.assemble( rowProcessingState, options );
final SharedSessionContractImplementor session = rowProcessingState
.getJdbcValuesSourceProcessingState()
.getSession();
//noinspection unchecked
return (T) session.internalLoad(
return (T) rowProcessingState.getSession().internalLoad(
entityMapping.getEntityName(),
keyValue,
eager,

View File

@ -17,6 +17,7 @@ import org.hibernate.mapping.Any;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.DiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingType;
@ -51,7 +52,7 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
private final NavigableRole partRole;
private final CollectionPersister collectionDescriptor;
private final DiscriminatedAssociationMapping discriminatorMapping;
private final DiscriminatedAssociationMapping associationMapping;
public DiscriminatedCollectionPart(
Nature nature,
@ -64,7 +65,7 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
this.partRole = collectionDescriptor.getNavigableRole().append( nature.getName() );
this.collectionDescriptor = collectionDescriptor;
this.discriminatorMapping = DiscriminatedAssociationMapping.from(
this.associationMapping = DiscriminatedAssociationMapping.from(
partRole,
baseAssociationJtd,
this,
@ -80,29 +81,34 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
}
@Override
public BasicValuedModelPart getDiscriminatorPart() {
return discriminatorMapping.getDiscriminatorPart();
public DiscriminatorMapping getDiscriminatorMapping() {
return associationMapping.getDiscriminatorPart();
}
@Override
public void applyDiscriminator(Consumer<Predicate> predicateConsumer, String alias, TableGroup tableGroup, SqlAstCreationState creationState) {
throw new UnsupportedOperationException();
}
@Override
public BasicValuedModelPart getKeyPart() {
return discriminatorMapping.getKeyPart();
return associationMapping.getKeyPart();
}
@Override
public EntityMappingType resolveDiscriminatorValue(Object discriminatorValue) {
return discriminatorMapping.resolveDiscriminatorValueToEntityMapping( discriminatorValue );
return associationMapping.resolveDiscriminatorValueToEntityMapping( discriminatorValue );
}
@Override
public Object resolveDiscriminatorForEntityType(EntityMappingType entityMappingType) {
return discriminatorMapping.resolveDiscriminatorValueToEntityMapping( entityMappingType );
return associationMapping.resolveDiscriminatorValueToEntityMapping( entityMappingType );
}
@Override
public int forEachSelectable(int offset, SelectableConsumer consumer) {
discriminatorMapping.getDiscriminatorPart().forEachSelectable( offset, consumer );
discriminatorMapping.getKeyPart().forEachSelectable( offset + 1, consumer );
associationMapping.getDiscriminatorPart().forEachSelectable( offset, consumer );
associationMapping.getKeyPart().forEachSelectable( offset + 1, consumer );
return 2;
}
@ -119,13 +125,13 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
@Override
public FetchOptions getMappedFetchOptions() {
return discriminatorMapping;
return associationMapping;
}
@Override
public boolean hasPartitionedSelectionMapping() {
return discriminatorMapping.getDiscriminatorPart().isPartitioned()
|| discriminatorMapping.getKeyPart().isPartitioned();
return associationMapping.getDiscriminatorPart().isPartitioned()
|| associationMapping.getKeyPart().isPartitioned();
}
@Override
@ -141,7 +147,7 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
boolean selected,
String resultVariable,
DomainResultCreationState creationState) {
return discriminatorMapping.generateFetch(
return associationMapping.generateFetch(
fetchParent,
fetchablePath,
fetchTiming,
@ -157,7 +163,7 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
TableGroup tableGroup,
String resultVariable,
DomainResultCreationState creationState) {
return discriminatorMapping.createDomainResult(
return associationMapping.createDomainResult(
navigablePath,
tableGroup,
resultVariable,
@ -170,7 +176,7 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
NavigablePath navigablePath,
TableGroup tableGroup,
DomainResultCreationState creationState) {
discriminatorMapping.getDiscriminatorPart().applySqlSelections( navigablePath, tableGroup, creationState );
associationMapping.getDiscriminatorPart().applySqlSelections( navigablePath, tableGroup, creationState );
}
@Override
@ -179,17 +185,17 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
TableGroup tableGroup,
DomainResultCreationState creationState,
BiConsumer<SqlSelection, JdbcMapping> selectionConsumer) {
discriminatorMapping.getDiscriminatorPart().applySqlSelections( navigablePath, tableGroup, creationState, selectionConsumer );
associationMapping.getDiscriminatorPart().applySqlSelections( navigablePath, tableGroup, creationState, selectionConsumer );
}
@Override
public MappingType getPartMappingType() {
return discriminatorMapping;
return associationMapping;
}
@Override
public JavaType<?> getJavaType() {
return discriminatorMapping.getJavaType();
return associationMapping.getJavaType();
}
@Override
@ -214,7 +220,7 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
@Override
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
return discriminatorMapping.findSubPart( name, treatTargetType );
return associationMapping.findSubPart( name, treatTargetType );
}
@Override
@ -262,12 +268,12 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
return discriminatorMapping.getDiscriminatorPart().disassemble( value, session );
return associationMapping.getDiscriminatorPart().disassemble( value, session );
}
@Override
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
discriminatorMapping.getDiscriminatorPart().addToCacheKey( cacheKey, value, session );
associationMapping.getDiscriminatorPart().addToCacheKey( cacheKey, value, session );
}
@Override
@ -278,7 +284,7 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
Y y,
JdbcValuesBiConsumer<X, Y> valuesConsumer,
SharedSessionContractImplementor session) {
return discriminatorMapping.getDiscriminatorPart().forEachDisassembledJdbcValue(
return associationMapping.getDiscriminatorPart().forEachDisassembledJdbcValue(
value,
offset,
x,
@ -296,7 +302,7 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return discriminatorMapping.breakDownJdbcValues( offset, x, y, domainValue, valueConsumer, session );
return associationMapping.breakDownJdbcValues( offset, x, y, domainValue, valueConsumer, session );
}
@Override
@ -307,7 +313,7 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return discriminatorMapping.decompose( offset, x, y, domainValue, valueConsumer, session );
return associationMapping.decompose( offset, x, y, domainValue, valueConsumer, session );
}
@Override

View File

@ -0,0 +1,67 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.metamodel.mapping.internal;
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
import org.hibernate.metamodel.mapping.DiscriminatorType;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
/**
* Specialization of ConvertedBasicTypeImpl to expose access to the
* {@link #underlyingJdbcMapping} of this discriminator - the bit that handles
* the relationship between the relational JavaType and the JdbcType
*
* @author Steve Ebersole
*/
public class DiscriminatorTypeImpl<O> extends ConvertedBasicTypeImpl<O> implements DiscriminatorType<O> {
private final JavaType<O> domainJavaType;
private final BasicType<?> underlyingJdbcMapping;
public DiscriminatorTypeImpl(
BasicType<?> underlyingJdbcMapping,
DiscriminatorConverter<O,?> discriminatorValueConverter) {
super(
discriminatorValueConverter.getNavigableRole().getFullPath(),
"Discriminator type " + discriminatorValueConverter.getNavigableRole().getFullPath(),
underlyingJdbcMapping.getJdbcType(),
discriminatorValueConverter
);
assert underlyingJdbcMapping.getJdbcJavaType() == discriminatorValueConverter.getRelationalJavaType();
this.domainJavaType = discriminatorValueConverter.getDomainJavaType();
this.underlyingJdbcMapping = underlyingJdbcMapping;
}
@Override
public BasicType<?> getUnderlyingJdbcMapping() {
return underlyingJdbcMapping;
}
@SuppressWarnings("rawtypes")
@Override
public DiscriminatorConverter getValueConverter() {
return (DiscriminatorConverter) super.getValueConverter();
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Class getJavaType() {
return domainJavaType.getJavaTypeClass();
}
@Override
public boolean canDoExtraction() {
return underlyingJdbcMapping.canDoExtraction();
}
@Override
public JavaType<O> getExpressibleJavaType() {
return domainJavaType;
}
}

View File

@ -4,24 +4,20 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.persister.entity;
package org.hibernate.metamodel.mapping.internal;
import org.hibernate.Internal;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.DiscriminatorValueDetails;
import org.hibernate.metamodel.mapping.EntityMappingType;
/**
* @author Steve Ebersole
*/
@Internal
public class DiscriminatorValueDetailsImpl implements EntityDiscriminatorMapping.DiscriminatorValueDetails {
public class DiscriminatorValueDetailsImpl implements DiscriminatorValueDetails {
private final Object value;
private final String jdbcLiteral;
private final EntityMappingType matchedEntityDescriptor;
public DiscriminatorValueDetailsImpl(Object value, String jdbcLiteral, EntityMappingType matchedEntityDescriptor) {
public DiscriminatorValueDetailsImpl(Object value, EntityMappingType matchedEntityDescriptor) {
this.value = value;
this.jdbcLiteral = jdbcLiteral;
this.matchedEntityDescriptor = matchedEntityDescriptor;
}
@ -30,11 +26,6 @@ public class DiscriminatorValueDetailsImpl implements EntityDiscriminatorMapping
return value;
}
@Override
public Object getSqlLiteralValue() {
return jdbcLiteral;
}
@Override
public EntityMappingType getIndicatedEntity() {
return matchedEntityDescriptor;

View File

@ -6,17 +6,18 @@
*/
package org.hibernate.metamodel.mapping.internal;
import java.util.Map;
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.persister.entity.DiscriminatorType;
import org.hibernate.metamodel.mapping.DiscriminatorType;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.type.BasicType;
/**
* @author Steve Ebersole
@ -42,9 +43,9 @@ public class ExplicitColumnDiscriminatorMappingImpl extends AbstractDiscriminato
Integer precision,
Integer scale,
DiscriminatorType<?> discriminatorType,
Map<Object, DiscriminatorValueDetails> valueMappings,
MappingModelCreationProcess creationProcess) {
super( entityDescriptor, discriminatorType, valueMappings, creationProcess );
//noinspection unchecked
super( entityDescriptor, (DiscriminatorType<Object>) discriminatorType, (BasicType<Object>) discriminatorType.getUnderlyingJdbcMapping() );
this.tableExpression = tableExpression;
this.isPhysical = isPhysical;
this.columnDefinition = columnDefinition;
@ -61,6 +62,16 @@ public class ExplicitColumnDiscriminatorMappingImpl extends AbstractDiscriminato
}
}
@Override
public DiscriminatorType getMappedType() {
return (DiscriminatorType) super.getMappedType();
}
@Override
public DiscriminatorConverter<?, ?> getValueConverter() {
return getMappedType().getValueConverter();
}
@Override
public Expression resolveSqlExpression(
NavigablePath navigablePath,

View File

@ -10,7 +10,7 @@ package org.hibernate.metamodel.model.domain;
/**
* Models Hibernate's ANY mapping (reverse discrimination) as a JPA domain model type
*
* @param <J> The base Java type defined for the any mapping
* @param <J> The base Java type defined for the {@code any} mapping
*
* @author Steve Ebersole
*/

View File

@ -0,0 +1,42 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.metamodel.model.domain;
import org.hibernate.metamodel.UnsupportedMappingException;
import org.hibernate.query.PathException;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
/**
* Commonality between entity and any discriminators
*
* @author Steve Ebersole
*/
public interface DiscriminatorSqmPath<T> extends SqmPath<T> {
@Override
default void appendHqlString(StringBuilder sb) {
sb.append( "type(" );
getLhs().appendHqlString( sb );
sb.append( ')' );
}
@Override
default SqmPath<?> resolvePathPart(String name, boolean isTerminal, SqmCreationState creationState) {
throw new IllegalStateException( "Discriminator cannot be de-referenced" );
}
@Override
default SqmTreatedPath treatAs(Class treatJavaType) throws PathException {
throw new UnsupportedMappingException( "Cannot apply TREAT operator to discriminator path" );
}
@Override
default SqmTreatedPath treatAs(EntityDomainType treatTarget) throws PathException {
throw new UnsupportedMappingException( "Cannot apply TREAT operator to discriminator path" );
}
}

View File

@ -1,71 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.persister.entity.EntityPersister;
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.spi.TypeConfiguration;
public class AnyDiscriminatorConverter implements BasicValueConverter<Class, Object> {
private final MetaType modelPart;
private final BasicType discriminatorBasicType;
private final TypeConfiguration typeConfiguration;
private final MappingMetamodel mappingMetamodel;
public AnyDiscriminatorConverter(
MetaType modelPart,
BasicType discriminatorBasicType,
TypeConfiguration typeConfiguration,
MappingMetamodel mappingMetamodel) {
this.modelPart = modelPart;
this.discriminatorBasicType = discriminatorBasicType;
this.typeConfiguration = typeConfiguration;
this.mappingMetamodel = mappingMetamodel;
}
@Override
public Class toDomainValue(Object discriminatorValue) {
if ( discriminatorValue == null ) {
return null;
}
final String entityName = modelPart.getDiscriminatorValuesToEntityNameMap().get( discriminatorValue );
final EntityPersister entityDescriptor = mappingMetamodel.getEntityDescriptor( entityName );
assert entityDescriptor.getRepresentationStrategy().getMode() == RepresentationMode.POJO;
return entityDescriptor.getJavaType().getJavaTypeClass();
}
@Override
public Object toRelationalValue(Class domainForm) {
if ( domainForm == null ) {
return null;
}
return modelPart.getEntityNameToDiscriminatorValueMap().get( ( domainForm ).getName() );
}
@Override
public JavaType<Class> getDomainJavaType() {
return getExpressibleJavaType();
}
@Override
public JavaType<Object> getRelationalJavaType() {
return discriminatorBasicType.getJavaTypeDescriptor();
}
public JavaType<Class> getExpressibleJavaType() {
return ClassJavaType.INSTANCE;
}
}

View File

@ -6,20 +6,16 @@
*/
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.UnsupportedMappingException;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.PathException;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.metamodel.model.domain.DiscriminatorSqmPath;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.domain.AbstractSqmPath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
import org.hibernate.spi.NavigablePath;
public class AnyDiscriminatorSqmPath<T> extends AbstractSqmPath<T> {
public class AnyDiscriminatorSqmPath<T> extends AbstractSqmPath<T> implements DiscriminatorSqmPath<T> {
protected AnyDiscriminatorSqmPath(
NavigablePath navigablePath,
@ -46,28 +42,6 @@ public class AnyDiscriminatorSqmPath<T> extends AbstractSqmPath<T> {
return walker.visitAnyDiscriminatorTypeExpression( this ) ;
}
@Override
public void appendHqlString(StringBuilder sb) {
sb.append( "type(" );
getLhs().appendHqlString( sb );
sb.append( ')' );
}
@Override
public SqmPath<?> resolvePathPart(String name, boolean isTerminal, SqmCreationState creationState) {
throw new IllegalStateException( "Discriminator cannot be de-referenced" );
}
@Override
public SqmTreatedPath treatAs(Class treatJavaType) throws PathException {
throw new UnsupportedMappingException( "Cannot apply TREAT operator to discriminator path" );
}
@Override
public SqmTreatedPath treatAs(EntityDomainType treatTarget) throws PathException {
throw new UnsupportedMappingException( "Cannot apply TREAT operator to discriminator path" );
}
@Override
public AnyDiscriminatorSqmPathSource<T> getExpressible() {
return (AnyDiscriminatorSqmPathSource<T>) getNodeType();

View File

@ -6,13 +6,24 @@
*/
package org.hibernate.metamodel.model.domain.internal;
import java.util.List;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.Column;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
import org.hibernate.metamodel.mapping.internal.AnyDiscriminatorPart;
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.type.AnyType;
import org.hibernate.type.BasicType;
import org.hibernate.type.MetaType;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.type.descriptor.java.ClassJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.ObjectJavaType;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
@ -24,26 +35,52 @@ public class AnyMappingDomainTypeImpl implements AnyMappingDomainType<Class> {
private final JavaType<Class> baseJtd;
private final BasicType<Class> anyDiscriminatorType;
@SuppressWarnings({ "unchecked", "rawtypes" })
public AnyMappingDomainTypeImpl(
Any bootAnyMapping,
AnyType anyType,
JavaType<Class> baseJtd,
TypeConfiguration typeConfiguration,
MappingMetamodel mappingMetamodel) {
MappingMetamodel mappingMetamodel,
SessionFactoryImplementor sessionFactory) {
this.anyType = anyType;
this.baseJtd = baseJtd;
final MetaType discriminatorType = (MetaType) anyType.getDiscriminatorType();
final BasicType discriminatorBasicType = (BasicType) discriminatorType.getBaseType();
anyDiscriminatorType =
new ConvertedBasicTypeImpl<>(
null, // no name
discriminatorBasicType.getJdbcType(),
new AnyDiscriminatorConverter(
discriminatorType,
discriminatorBasicType,
typeConfiguration,
mappingMetamodel
)
);
final BasicType discriminatorBaseType = (BasicType) discriminatorType.getBaseType();
final NavigableRole navigableRole = resolveNavigableRole( bootAnyMapping );
anyDiscriminatorType = new ConvertedBasicTypeImpl<>(
navigableRole.getFullPath(),
discriminatorBaseType.getJdbcType(),
DiscriminatorConverter.fromValueMappings(
navigableRole,
(JavaType) ClassJavaType.INSTANCE,
discriminatorBaseType,
bootAnyMapping.getMetaValues(),
sessionFactory
)
);
}
private NavigableRole resolveNavigableRole(Any bootAnyMapping) {
final StringBuilder buffer = new StringBuilder();
if ( bootAnyMapping.getTable() != null ) {
buffer.append( bootAnyMapping.getTable().getName() );
}
buffer.append( "(" );
final List<Column> columns = bootAnyMapping.getColumns();
for ( int i = 0; i < columns.size(); i++ ) {
buffer.append( columns.get( i ).getName() );
if ( i+1 < columns.size() ) {
// still more columns
buffer.append( "," );
}
}
buffer.append( ")" );
return new NavigableRole( buffer.toString() );
}
@Override

View File

@ -43,7 +43,7 @@ public class DiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
}
return new DiscriminatorSqmPath( navigablePath, pathModel, lhs, entityDomainType, entityMapping, lhs.nodeBuilder() );
return new EntityDiscriminatorSqmPath( navigablePath, pathModel, lhs, entityDomainType, entityMapping, lhs.nodeBuilder() );
}
@Override

View File

@ -6,18 +6,14 @@
*/
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.UnsupportedMappingException;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.PathException;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.domain.AbstractSqmPath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
import org.hibernate.spi.NavigablePath;
@ -27,11 +23,11 @@ import org.hibernate.spi.NavigablePath;
* @author Steve Ebersole
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class DiscriminatorSqmPath extends AbstractSqmPath {
public class EntityDiscriminatorSqmPath extends AbstractSqmPath implements org.hibernate.metamodel.model.domain.DiscriminatorSqmPath {
private final EntityDomainType entityDomainType;
private final EntityMappingType entityDescriptor;
protected DiscriminatorSqmPath(
protected EntityDiscriminatorSqmPath(
NavigablePath navigablePath,
SqmPathSource referencedPathSource,
SqmPath<?> lhs,
@ -52,14 +48,19 @@ public class DiscriminatorSqmPath extends AbstractSqmPath {
}
@Override
public DiscriminatorSqmPath copy(SqmCopyContext context) {
final DiscriminatorSqmPath existing = context.getCopy( this );
public DiscriminatorSqmPathSource getExpressible() {
return (DiscriminatorSqmPathSource) getNodeType();
}
@Override
public EntityDiscriminatorSqmPath copy(SqmCopyContext context) {
final EntityDiscriminatorSqmPath existing = context.getCopy( this );
if ( existing != null ) {
return existing;
}
return context.registerCopy(
this,
(DiscriminatorSqmPath) getLhs().copy( context ).type()
(EntityDiscriminatorSqmPath) getLhs().copy( context ).type()
);
}
@ -71,26 +72,4 @@ public class DiscriminatorSqmPath extends AbstractSqmPath {
return walker.visitDiscriminatorPath( this );
}
@Override
public void appendHqlString(StringBuilder sb) {
sb.append( "type(" );
getLhs().appendHqlString( sb );
sb.append( ')' );
}
@Override
public SqmPath<?> resolvePathPart(String name, boolean isTerminal, SqmCreationState creationState) {
throw new IllegalStateException( "Discriminator cannot be de-referenced" );
}
@Override
public SqmTreatedPath treatAs(Class treatJavaType) throws PathException {
throw new UnsupportedMappingException( "Cannot apply TREAT operator to discriminator path" );
}
@Override
public SqmTreatedPath treatAs(EntityDomainType treatTarget) throws PathException {
throw new UnsupportedMappingException( "Cannot apply TREAT operator to discriminator path" );
}
}

View File

@ -25,7 +25,6 @@ import java.util.Objects;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
@ -154,9 +153,10 @@ import org.hibernate.metamodel.mapping.AttributeMappingsMap;
import org.hibernate.metamodel.mapping.AttributeMetadata;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
import org.hibernate.metamodel.mapping.DiscriminatorType;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping.DiscriminatorValueDetails;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.EntityRowIdMapping;
@ -176,11 +176,13 @@ import org.hibernate.metamodel.mapping.VirtualModelPart;
import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl;
import org.hibernate.metamodel.mapping.internal.CompoundNaturalIdMapping;
import org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping;
import org.hibernate.metamodel.mapping.internal.DiscriminatorTypeImpl;
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
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.GeneratedValuesProcessor;
import org.hibernate.metamodel.mapping.internal.ImmutableAttributeMappingList;
import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
@ -190,7 +192,6 @@ import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.spi.EntityInstantiator;
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.mutation.DeleteCoordinator;
@ -200,7 +201,6 @@ import org.hibernate.persister.entity.mutation.InsertCoordinator;
import org.hibernate.persister.entity.mutation.UpdateCoordinator;
import org.hibernate.persister.entity.mutation.UpdateCoordinatorNoOp;
import org.hibernate.persister.entity.mutation.UpdateCoordinatorStandard;
import org.hibernate.metamodel.mapping.internal.ImmutableAttributeMappingList;
import org.hibernate.persister.internal.SqlFragmentPredicate;
import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.property.access.spi.PropertyAccess;
@ -271,7 +271,7 @@ import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import static java.util.Collections.emptyList;
@ -299,7 +299,6 @@ import static org.hibernate.internal.util.collections.CollectionHelper.toSmallLi
import static org.hibernate.metamodel.RepresentationMode.POJO;
import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR;
import static org.hibernate.persister.entity.DiscriminatorHelper.NULL_DISCRIMINATOR;
import static org.hibernate.persister.entity.DiscriminatorHelper.discriminatorLiteral;
import static org.hibernate.pretty.MessageHelper.infoString;
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
@ -2196,21 +2195,49 @@ public abstract class AbstractEntityPersister
return ( (PluralAttributeMapping) attributeMapping ).getKeyDescriptor().getKeyTable();
}
private DiscriminatorMetadata discriminatorMetadata;
private DiscriminatorType discriminatorType;
protected DiscriminatorType resolveDiscriminatorType() {
if ( discriminatorType == null ) {
discriminatorType = buildDiscriminatorType();
}
return discriminatorType;
}
private DiscriminatorType buildDiscriminatorType() {
final BasicType<?> underlingJdbcMapping = getDiscriminatorType();
if ( underlingJdbcMapping == null ) {
return null;
}
final JavaTypeRegistry javaTypeRegistry = factory.getTypeConfiguration().getJavaTypeRegistry();
final JavaType<Object> domainJavaType;
if ( representationStrategy.getMode() == POJO
&& getEntityName().equals( getJavaType().getJavaTypeClass().getName() ) ) {
domainJavaType = javaTypeRegistry.resolveDescriptor( Class.class );
}
else {
domainJavaType = javaTypeRegistry.resolveDescriptor( String.class );
}
//noinspection rawtypes
final DiscriminatorConverter converter = DiscriminatorConverter.fromValueMappings(
getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME ),
domainJavaType,
underlingJdbcMapping,
getSubclassByDiscriminatorValue(),
factory
);
//noinspection unchecked,rawtypes
return new DiscriminatorTypeImpl( underlingJdbcMapping, converter );
}
@Override
public DiscriminatorMetadata getTypeDiscriminatorMetadata() {
if ( discriminatorMetadata == null ) {
discriminatorMetadata = buildTypeDiscriminatorMetadata();
}
return discriminatorMetadata;
}
private DiscriminatorMetadata buildTypeDiscriminatorMetadata() {
return () -> {
final BasicType<?> type = getDiscriminatorType();
return type == null ? null : new DiscriminatorType<>( type, AbstractEntityPersister.this );
};
return this::buildDiscriminatorType;
}
public static String generateTableAlias(String rootAlias, int tableNumber) {
@ -5005,7 +5032,6 @@ public abstract class AbstractEntityPersister
isPhysicalDiscriminator(),
columnDefinition, length, precision, scale,
(DiscriminatorType<?>) getTypeDiscriminatorMetadata().getResolutionType(),
buildDiscriminatorValueMappings( modelCreationProcess ),
modelCreationProcess
);
}
@ -5014,27 +5040,6 @@ public abstract class AbstractEntityPersister
@Override
public abstract BasicType<?> getDiscriminatorType();
protected Map<Object, DiscriminatorValueDetails> buildDiscriminatorValueMappings(
MappingModelCreationProcess modelCreationProcess) {
final MappingMetamodelImplementor mappingModel =
modelCreationProcess.getCreationContext().getDomainModel();
//noinspection unchecked
final JdbcLiteralFormatter<Object> jdbcLiteralFormatter =
(JdbcLiteralFormatter<Object>) getDiscriminatorType().getJdbcLiteralFormatter();
final Dialect dialect = modelCreationProcess.getCreationContext().getDialect();
final Map<Object, DiscriminatorValueDetails> valueMappings = new ConcurrentHashMap<>();
getSubclassByDiscriminatorValue().forEach( (value, entityName) -> {
final DiscriminatorValueDetailsImpl valueMapping = new DiscriminatorValueDetailsImpl(
value,
discriminatorLiteral( jdbcLiteralFormatter, dialect, value ),
mappingModel.findEntityDescriptor( entityName )
);
valueMappings.put( value, valueMapping );
} );
return valueMappings;
}
protected EntityVersionMapping generateVersionMapping(
Supplier<?> templateInstanceCreator,
PersistentClass bootEntityDescriptor,

View File

@ -27,6 +27,10 @@ public class DiscriminatorHelper {
public static final Object NULL_DISCRIMINATOR = new MarkerObject( "<null discriminator>" );
public static final Object NOT_NULL_DISCRIMINATOR = new MarkerObject( "<not null discriminator>" );
/**
* The underlying BasicType as the "JDBC mapping" between the relational {@link org.hibernate.type.descriptor.java.JavaType}
* and the {@link org.hibernate.type.descriptor.jdbc.JdbcType}.
*/
static BasicType<?> getDiscriminatorType(PersistentClass persistentClass) {
Type discriminatorType = persistentClass.getDiscriminator().getType();
if ( discriminatorType instanceof BasicType ) {

View File

@ -5,14 +5,21 @@
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.persister.entity;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
import org.hibernate.type.MetaType;
import org.hibernate.type.Type;
/**
* Provides the information needed to properly handle type discrimination
* in HQL queries, either by 'something.class' or 'type(something)' references.
*
* @deprecated The functionality of DiscriminatorMetadata, {@link DiscriminatorType} and {@link MetaType} have been
* consolidated into {@link EntityDiscriminatorMapping} and {@link DiscriminatorConverter}
*
* @author Steve Ebersole
*/
@Deprecated( since = "6.2", forRemoval = true )
public interface DiscriminatorMetadata {
/**

View File

@ -21,12 +21,11 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping.DiscriminatorValueDetails;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.DiscriminatorConverter;
import org.hibernate.type.AbstractType;
import org.hibernate.type.BasicType;
import org.hibernate.type.MetaType;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.java.ClassJavaType;
@ -36,16 +35,25 @@ import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType;
/**
* @deprecated The functionality of DiscriminatorType, {@link DiscriminatorMetadata} and {@link MetaType} have been
* consolidated into {@link EntityDiscriminatorMapping} and {@link DiscriminatorConverter}
*
* @author Steve Ebersole
*/
@Internal
public class DiscriminatorType<T> extends AbstractType implements BasicType<T>, BasicValueConverter<T, Object> {
@Deprecated( since = "6.2", forRemoval = true )
public class DiscriminatorType<T> extends AbstractType implements BasicType<T> {
private final BasicType<Object> underlyingType;
private final Loadable persister;
private final DiscriminatorConverter converter;
public DiscriminatorType(BasicType<?> underlyingType, Loadable persister) {
public DiscriminatorType(
BasicType<?> underlyingType,
Loadable persister,
DiscriminatorConverter converter) {
this.underlyingType = (BasicType<Object>) underlyingType;
this.persister = persister;
this.converter = converter;
}
public BasicType<?> getUnderlyingType() {
@ -53,8 +61,8 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
}
@Override
public BasicValueConverter<T, ?> getValueConverter() {
return this;
public DiscriminatorConverter getValueConverter() {
return converter;
}
@Override
@ -62,52 +70,6 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
return underlyingType.getJdbcJavaType();
}
@Override
public T toDomainValue(Object discriminatorValue) {
if ( discriminatorValue == null ) {
return null;
}
final DiscriminatorValueDetails valueDetails = persister.getDiscriminatorMapping().resolveDiscriminatorValue( discriminatorValue );
if ( valueDetails == null ) {
throw new HibernateException( "Unable to resolve discriminator value [" + discriminatorValue + "] to entity name" );
}
final EntityMappingType indicatedEntity = valueDetails.getIndicatedEntity();
//noinspection unchecked
return indicatedEntity.getRepresentationStrategy().getMode() == RepresentationMode.POJO
? (T) indicatedEntity.getJavaType().getJavaTypeClass()
: (T) indicatedEntity.getEntityName();
}
@Override
public Object toRelationalValue(T domainForm) {
if ( domainForm == null ) {
return null;
}
final MappingMetamodelImplementor mappingMetamodel = persister.getFactory()
.getRuntimeMetamodels()
.getMappingMetamodel();
final Loadable loadable;
if ( domainForm instanceof Class<?> ) {
loadable = (Loadable) mappingMetamodel.getEntityDescriptor( (Class<?>) domainForm );
}
else {
loadable = (Loadable) mappingMetamodel.getEntityDescriptor( (String) domainForm );
}
return loadable.getDiscriminatorValue();
}
@Override
public JavaType<T> getDomainJavaType() {
return getExpressibleJavaType();
}
@Override
public JavaType<Object> getRelationalJavaType() {
return underlyingType.getExpressibleJavaType();
}
@Override
public Class<?> getReturnedClass() {
return Class.class;
@ -132,14 +94,16 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
public T extract(CallableStatement statement, int paramIndex, SharedSessionContractImplementor session)
throws SQLException {
final Object discriminatorValue = underlyingType.extract( statement, paramIndex, session );
return toDomainValue( discriminatorValue );
//noinspection unchecked
return (T) converter.toDomainValue( discriminatorValue );
}
@Override
public T extract(CallableStatement statement, String paramName, SharedSessionContractImplementor session)
throws SQLException {
final Object discriminatorValue = underlyingType.extract( statement, paramName, session );
return toDomainValue( discriminatorValue );
//noinspection unchecked
return (T) converter.toDomainValue( discriminatorValue );
}
@Override
@ -158,7 +122,9 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
Object value,
int index,
SharedSessionContractImplementor session) throws HibernateException, SQLException {
underlyingType.nullSafeSet( st, toRelationalValue( (T) value ), index, session);
//noinspection unchecked
final Object relationalValue = converter.toRelationalValue( value );
underlyingType.nullSafeSet( st, relationalValue, index, session);
}
@Override
@ -193,7 +159,8 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
return toRelationalValue( (T) value );
//noinspection unchecked
return converter.toRelationalValue( value );
}
@Override

View File

@ -69,8 +69,8 @@ import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.CompositeType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.hibernate.type.spi.TypeConfiguration;
import org.jboss.logging.Logger;
import static java.util.Collections.emptyMap;
@ -1236,9 +1236,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
notNullColumnNames,
discriminatorValues,
discriminatorAbstract,
subclassNameByTableName,
(DiscriminatorType<?>) getTypeDiscriminatorMetadata().getResolutionType(),
buildDiscriminatorValueMappings( modelCreationProcess ),
resolveDiscriminatorType(),
modelCreationProcess
);
}

View File

@ -9,7 +9,7 @@ package org.hibernate.query.sqm;
import java.util.List;
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.internal.DiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.internal.EntityDiscriminatorSqmPath;
import org.hibernate.query.sqm.tree.cte.SqmCteContainer;
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement;
@ -232,7 +232,7 @@ public interface SemanticQueryWalker<T> {
T visitFkExpression(SqmFkExpression<?> fkExpression);
T visitDiscriminatorPath(DiscriminatorSqmPath sqmPath);
T visitDiscriminatorPath(EntityDiscriminatorSqmPath sqmPath);
T visitIndexedPluralAccessPath(SqmIndexedCollectionAccessPath<?> path);

View File

@ -10,7 +10,7 @@ import java.util.List;
import java.util.Locale;
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.internal.DiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.internal.EntityDiscriminatorSqmPath;
import org.hibernate.query.QueryLogging;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.SqmStatement;
@ -689,7 +689,7 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
}
@Override
public Object visitDiscriminatorPath(DiscriminatorSqmPath sqmPath) {
public Object visitDiscriminatorPath(EntityDiscriminatorSqmPath sqmPath) {
logWithIndentation( "-> [discriminator-path] - `%s`", sqmPath.getNavigablePath() );
return null;

View File

@ -9,7 +9,7 @@ package org.hibernate.query.sqm.spi;
import java.util.List;
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.internal.DiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.internal.EntityDiscriminatorSqmPath;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.SqmVisitableNode;
import org.hibernate.query.sqm.tree.cte.SqmCteContainer;
@ -364,7 +364,7 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
}
@Override
public Object visitDiscriminatorPath(DiscriminatorSqmPath path) {
public Object visitDiscriminatorPath(EntityDiscriminatorSqmPath path) {
return path;
}

View File

@ -89,10 +89,6 @@ import org.hibernate.metamodel.mapping.internal.OneToManyCollectionPart;
import org.hibernate.metamodel.mapping.internal.SqlTypedMappingImpl;
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
import org.hibernate.metamodel.mapping.ordering.OrderByFragment;
import org.hibernate.query.sqm.sql.internal.DiscriminatorPathInterpretation;
import org.hibernate.sql.results.graph.collection.internal.EagerCollectionFetch;
import org.hibernate.type.descriptor.converter.internal.OrdinalEnumValueConverter;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
@ -101,7 +97,7 @@ import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPathSource;
import org.hibernate.metamodel.model.domain.internal.BasicSqmPathSource;
import org.hibernate.metamodel.model.domain.internal.CompositeSqmPathSource;
import org.hibernate.metamodel.model.domain.internal.DiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.internal.EntityDiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.internal.EmbeddedSqmPathSource;
import org.hibernate.metamodel.model.domain.internal.EntityTypeImpl;
import org.hibernate.persister.entity.AbstractEntityPersister;
@ -142,9 +138,10 @@ import org.hibernate.query.sqm.internal.SqmMappingModelHelper;
import org.hibernate.query.sqm.mutation.internal.SqmInsertStrategyHelper;
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
import org.hibernate.query.sqm.spi.BaseSemanticQueryWalker;
import org.hibernate.query.sqm.sql.internal.AnyDiscriminatorPathInterpretation;
import org.hibernate.query.sqm.sql.internal.BasicValuedPathInterpretation;
import org.hibernate.query.sqm.sql.internal.DiscriminatedAssociationPathInterpretation;
import org.hibernate.query.sqm.sql.internal.DiscriminatedAssociationTypePathInterpretation;
import org.hibernate.query.sqm.sql.internal.DiscriminatorPathInterpretation;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.query.sqm.sql.internal.EmbeddableValuedExpression;
import org.hibernate.query.sqm.sql.internal.EmbeddableValuedPathInterpretation;
@ -382,21 +379,23 @@ import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.sql.results.graph.collection.internal.EagerCollectionFetch;
import org.hibernate.sql.results.graph.entity.EntityResultGraphNode;
import org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiation;
import org.hibernate.sql.results.graph.internal.ImmutableFetchList;
import org.hibernate.sql.results.internal.SqlSelectionImpl;
import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl;
import org.hibernate.type.BasicType;
import org.hibernate.type.CustomType;
import org.hibernate.type.EnumType;
import org.hibernate.type.JavaObjectType;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.converter.internal.OrdinalEnumValueConverter;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.type.descriptor.java.EnumJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.JavaTypeHelper;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.UserVersionType;
import org.hibernate.usertype.internal.AbstractTimeZoneStorageCompositeUserType;
@ -2905,7 +2904,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
}
}
protected void registerTypeUsage(DiscriminatorSqmPath path) {
protected void registerTypeUsage(EntityDiscriminatorSqmPath path) {
// When we encounter a discriminator path i.e. a use of `type( alias )`
// we have to resolve all subclass tables, otherwise we might get wrong results
// It might be worth deferring this process to the pruning phase when we start to prune subclass joins in more cases
@ -4106,7 +4105,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
return withTreatRestriction(
prepareReusablePath(
sqmPath,
() -> DiscriminatedAssociationTypePathInterpretation.from( sqmPath, this )
() -> AnyDiscriminatorPathInterpretation.from( sqmPath, this )
),
sqmPath
);
@ -4160,7 +4159,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
}
@Override
public Object visitDiscriminatorPath(DiscriminatorSqmPath sqmPath) {
public Object visitDiscriminatorPath(EntityDiscriminatorSqmPath sqmPath) {
return prepareReusablePath(
sqmPath,
() -> {
@ -4797,7 +4796,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
.addAll( entityDescriptor.getSubclassEntityNames() );
return expression;
}
if ( wrappedPath instanceof DiscriminatorSqmPath ) {
if ( wrappedPath instanceof EntityDiscriminatorSqmPath ) {
// Note: If the columns that are accessed are not shared with other entities, we could avoid this wrapping
return createCaseExpression( wrappedPath, treatedPath.getTreatTarget(), expression );
}
@ -4851,7 +4850,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
private Predicate createTreatTypeRestriction(SqmPath<?> lhs, Set<String> subclassEntityNames) {
// Do what visitSelfInterpretingSqmPath does, except for calling preparingReusablePath
// as that would register a type usage for the table group that we don't want here
final DiscriminatorSqmPath discriminatorSqmPath = (DiscriminatorSqmPath) lhs.type();
final EntityDiscriminatorSqmPath discriminatorSqmPath = (EntityDiscriminatorSqmPath) lhs.type();
registerTypeUsage( discriminatorSqmPath );
final Expression typeExpression = DiscriminatorPathInterpretation.from( discriminatorSqmPath, this );
if ( subclassEntityNames.size() == 1 ) {
@ -6527,13 +6526,11 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
JavaType<N> relationalJtd) {
return new QueryLiteral<>(
sqmEnumLiteral.getEnumValue().ordinal(),
new CustomType<>(
new EnumType<>(
enumJtd.getJavaTypeClass(),
new OrdinalEnumValueConverter<>( enumJtd, jdbcType, relationalJtd ),
typeConfiguration
),
typeConfiguration
new ConvertedBasicTypeImpl<>(
null,
"Query literal implicit Enum type descriptor",
jdbcType,
new OrdinalEnumValueConverter<>( enumJtd, jdbcType, relationalJtd )
)
);
}

View File

@ -6,32 +6,25 @@
*/
package org.hibernate.query.sqm.sql.internal;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.internal.AnyDiscriminatorPart;
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableReference;
public class DiscriminatedAssociationTypePathInterpretation<T> extends AbstractSqmPathInterpretation<T> {
public class AnyDiscriminatorPathInterpretation<T> extends AbstractSqmPathInterpretation<T> {
private final Expression expression;
public static <T> DiscriminatedAssociationTypePathInterpretation<T> from(
AnyDiscriminatorSqmPath sqmPath,
public static <T> AnyDiscriminatorPathInterpretation<T> from(
AnyDiscriminatorSqmPath<?> sqmPath,
SqmToSqlAstConverter converter) {
final SqmPath lhs = sqmPath.getLhs();
final SqmPath<?> lhs = sqmPath.getLhs();
final TableGroup tableGroup = converter.getFromClauseAccess().findTableGroup( lhs.getNavigablePath() );
final ModelPart subPart = tableGroup.getModelPart();
@ -44,32 +37,21 @@ public class DiscriminatedAssociationTypePathInterpretation<T> extends AbstractS
mapping = (DiscriminatedAssociationModelPart) subPart;
}
final List<Expression> tupleExpressions = new ArrayList<>();
mapping.forEachSelectable(
(selectionIndex, selectableMapping) -> {
if ( selectableMapping instanceof AnyDiscriminatorPart ) {
final TableReference tableReference = tableGroup.getPrimaryTableReference();
final Expression expression = converter.getSqlExpressionResolver().resolveSqlExpression(
tableReference,
selectableMapping
);
tupleExpressions.add( expression );
}
}
final TableReference tableReference = tableGroup.getPrimaryTableReference();
final Expression expression = converter.getSqlExpressionResolver().resolveSqlExpression(
tableReference,
mapping.getDiscriminatorPart()
);
assert tupleExpressions.size() == 1;
return new DiscriminatedAssociationTypePathInterpretation<T>(
return new AnyDiscriminatorPathInterpretation<>(
sqmPath.getNavigablePath(),
mapping,
tableGroup,
tupleExpressions.get( 0 )
expression
);
}
public DiscriminatedAssociationTypePathInterpretation(
public AnyDiscriminatorPathInterpretation(
NavigablePath navigablePath,
ModelPart mapping,
TableGroup tableGroup,

View File

@ -6,16 +6,17 @@
*/
package org.hibernate.query.sqm.sql.internal;
import org.hibernate.metamodel.mapping.DiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ModelPartContainer;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.model.domain.internal.DiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.internal.EntityDiscriminatorSqmPath;
import org.hibernate.query.results.ResultSetMappingSqlSelection;
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.results.ResultSetMappingSqlSelection;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlSelection;
@ -34,6 +35,17 @@ import org.hibernate.type.spi.TypeConfiguration;
public class DiscriminatorPathInterpretation<T> extends AbstractSqmPathInterpretation<T> {
private final Expression expression;
public DiscriminatorPathInterpretation(
NavigablePath navigablePath,
DiscriminatorMapping mapping,
TableGroup tableGroup,
SqlAstCreationState sqlAstCreationState) {
super( navigablePath, mapping, tableGroup );
final JdbcMapping jdbcMappingToUse = mapping.getJdbcMapping();
expression = getDiscriminatorMapping().resolveSqlExpression( navigablePath, jdbcMappingToUse, tableGroup, sqlAstCreationState );
}
public DiscriminatorPathInterpretation(
NavigablePath navigablePath,
EntityMappingType mapping,
@ -46,7 +58,7 @@ public class DiscriminatorPathInterpretation<T> extends AbstractSqmPathInterpret
}
public static SqmPathInterpretation<?> from(
DiscriminatorSqmPath path,
EntityDiscriminatorSqmPath path,
SqmToSqlAstConverter converter) {
assert path.getEntityDescriptor().hasSubclasses();

View File

@ -13,7 +13,7 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.IndexedConsumer;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.persister.entity.DiscriminatorType;
import org.hibernate.metamodel.mapping.DiscriminatorType;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;

View File

@ -6,6 +6,8 @@
*/
package org.hibernate.sql.exec.internal;
import java.util.Locale;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.sql.exec.spi.JdbcParameterBinding;
@ -17,7 +19,9 @@ public class JdbcParameterBindingImpl implements JdbcParameterBinding {
private final Object bindValue;
public JdbcParameterBindingImpl(JdbcMapping jdbcMapping, Object bindValue) {
assert bindValue == null || jdbcMapping.getJdbcJavaType().isInstance( bindValue );
assert bindValue == null || jdbcMapping == null || jdbcMapping.getJdbcJavaType().isInstance( bindValue )
: String.format( Locale.ROOT, "Unexpected value type (expected : %s) : %s (%s)", jdbcMapping.getJdbcJavaType().getJavaTypeClass().getName(), bindValue, bindValue.getClass().getName() );
this.jdbcMapping = jdbcMapping;
this.bindValue = bindValue;
}

View File

@ -34,7 +34,7 @@ import org.hibernate.loader.ast.internal.CacheEntityLoaderHelper;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.AttributeMetadata;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping.DiscriminatorValueDetails;
import org.hibernate.metamodel.mapping.DiscriminatorValueDetails;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.EntityVersionMapping;

View File

@ -17,10 +17,18 @@ 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;
/**
* @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 )
public class MetaType extends AbstractType {
public static final String[] REGISTRATION_KEYS = ArrayHelper.EMPTY_STRING_ARRAY;