HHH-15837 - Cleanup the tuple package

This commit is contained in:
Steve Ebersole 2022-12-09 01:09:44 -06:00
parent 0b04dcef16
commit ac32410438
31 changed files with 387 additions and 92 deletions

View File

@ -43,6 +43,7 @@ import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.internal.RowTransformerDatabaseSnapshotImpl;
import org.hibernate.sql.results.spi.ListResultsConsumer;
import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes;
import org.jboss.logging.Logger;
@ -100,14 +101,11 @@ class DatabaseSnapshotExecutor {
final SqlExpressionResolver sqlExpressionResolver = state.getSqlExpressionResolver();
// We just need a literal to have a result set
domainResults.add(
new QueryLiteral<>(
null,
sessionFactory.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.INTEGER )
).createDomainResult( null, state )
);
final BasicType<Integer> resolved = sessionFactory.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.INTEGER );
final QueryLiteral<Integer> queryLiteral = new QueryLiteral<>( null, resolved );
domainResults.add( queryLiteral.createDomainResult( null, state ) );
final NavigablePath idNavigablePath = rootPath.append( entityDescriptor.getIdentifierMapping().getNavigableRole().getNavigableName() );
entityDescriptor.getIdentifierMapping().forEachSelectable(
(columnIndex, selection) -> {

View File

@ -8,6 +8,7 @@ package org.hibernate.metamodel.mapping;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.persister.entity.DiscriminatorType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.tree.expression.Expression;
@ -41,6 +42,8 @@ public interface EntityDiscriminatorMapping extends VirtualModelPart, BasicValue
return getPartName();
}
DiscriminatorType getDiscriminatorType();
String getConcreteEntityNameForDiscriminatorValue(Object value);
boolean isPhysical();

View File

@ -78,6 +78,19 @@ public interface EntityMappingType
String getEntityName();
/**
* Details for the table this persister maps.
*
* @see #getIdentifierTableDetails()
*/
TableDetails getMappedTableDetails();
/**
* Details for the table that defines the identifier column(s)
* for an entity hierarchy.
*/
TableDetails getIdentifierTableDetails();
@Override
default EntityMappingType findContainingEntityMapping() {
return this;
@ -176,6 +189,13 @@ public interface EntityMappingType
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Inheritance
/**
* Get the class that this class is mapped as a subclass of
*/
default String getMappedSuperclass() {
return getSuperMappingType().getEntityName();
}
default int getSubclassId() {
return getEntityPersister().getEntityMetamodel().getSubclassId();
}
@ -188,6 +208,23 @@ public interface EntityMappingType
return getEntityPersister().getEntityMetamodel().getSubclassEntityNames();
}
/**
* Is this class explicit polymorphism only?
*/
boolean isExplicitPolymorphism();
Object getDiscriminatorValue();
default String getDiscriminatorSQLValue() {
return getDiscriminatorValue().toString();
}
String getSubclassForDiscriminatorValue(Object value);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute mappings
AttributeMapping findDeclaredAttributeMapping(String name);
/**
@ -248,10 +285,6 @@ public interface EntityMappingType
EntityDiscriminatorMapping getDiscriminatorMapping();
Object getDiscriminatorValue();
String getSubclassForDiscriminatorValue(Object value);
EntityVersionMapping getVersionMapping();
NaturalIdMapping getNaturalIdMapping();

View File

@ -20,7 +20,36 @@ import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType;
/**
* Models the type of a thing that can be used as an expression in a SQL query
* Describes the mapping for things which can be expressed in a SQL query.
* <p/>
* Generally speaking this models a column. However, it can also model SQL
* tuples as well
* <p/>
* This includes details such as<ul>
* <li>
* the {@linkplain #getJavaTypeDescriptor() Java type} of the mapping
* </li>
* <li>
* the {@linkplain #getJdbcType() JDBC type} of the mapping
* </li>
* <li>
* how to {@linkplain #getJdbcValueExtractor() read} values
* from {@linkplain java.sql.ResultSet result-sets}
* as well as {@linkplain java.sql.CallableStatement callable parameters}
* </li>
* <li>
* how to {@linkplain #getJdbcValueBinder() write} values to
* {@linkplain java.sql.PreparedStatement JDBC statements}
* </li>
* </ul>
* <p/>
* Some mappings will have an associated {@linkplain #getValueConverter() value converter}.
* The {@linkplain #getJdbcValueExtractor() readers} and {@linkplain #getJdbcValueBinder() writers}
* for such mappings will already incorporate those conversions
* <p/>
* Some mappings support usage as SQL literals. Such mappings will return a non-null
* {@linkplain #getJdbcLiteralFormatter literal formatter} which handles formatting
* values as a SQL literal
*
* @author Steve Ebersole
*/

View File

@ -0,0 +1,77 @@
/*
* 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;
/**
* Details about a table
*
* @author Steve Ebersole
*/
public interface TableDetails {
/**
* The name of the table
*/
String getTableName();
/**
* Whether this table is the root for a given {@link ModelPartContainer}
*/
boolean isIdentifierTable();
/**
* Details about the primary key of a table
*/
interface KeyDetails {
/**
* Number of columns
*/
int getColumnCount();
/**
* Group of columns defined on the primary key
*/
List<KeyColumn> getKeyColumns();
/**
* Get a key column by relative position
*/
KeyColumn getKeyColumn(int position);
/**
* Visit each key column
*/
void forEachKeyColumn(KeyColumnConsumer consumer);
}
/**
* Details about a column within the key group
*/
interface KeyColumn {
/**
* The name of the column
*/
String getColumnName();
/**
* Describes the mapping between object and relational for this column
*/
JdbcMapping getJdbcMapping();
}
@FunctionalInterface
interface KeyColumnConsumer {
/**
* Callback a particular key column
*
* @param position The position of the column within the key group
* @param column The column details
*/
void consume(int position, KeyColumn column);
}
}

View File

@ -62,6 +62,11 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
return entityDescriptor;
}
@Override
public DiscriminatorType getDiscriminatorType() {
return discriminatorType;
}
public BasicType<?> getUnderlyingJdbcMappingType() {
return discriminatorType.getUnderlyingType();
}
@ -142,7 +147,7 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
}
@Override
public BasicFetch generateFetch(
public BasicFetch<?> generateFetch(
FetchParent fetchParent,
NavigablePath fetchablePath,
FetchTiming fetchTiming,

View File

@ -79,7 +79,7 @@ public class CaseStatementDiscriminatorMappingImpl extends AbstractDiscriminator
}
@Override
public BasicFetch generateFetch(
public BasicFetch<?> generateFetch(
FetchParent fetchParent,
NavigablePath fetchablePath,
FetchTiming fetchTiming,

View File

@ -19,14 +19,6 @@ import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.stream.Stream;
import jakarta.persistence.EntityGraph;
import jakarta.persistence.NamedAttributeNode;
import jakarta.persistence.NamedEntityGraph;
import jakarta.persistence.NamedSubgraph;
import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.EmbeddableType;
import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.ManagedType;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
@ -48,6 +40,7 @@ import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.internal.JpaMetaModelPopulationSetting;
import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
import org.hibernate.metamodel.internal.MetadataContext;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
@ -57,13 +50,22 @@ import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.DynamicModelJavaType;
import org.hibernate.type.descriptor.java.spi.EntityJavaType;
import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.EntityGraph;
import jakarta.persistence.NamedAttributeNode;
import jakarta.persistence.NamedEntityGraph;
import jakarta.persistence.NamedSubgraph;
import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.EmbeddableType;
import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.ManagedType;
import jakarta.persistence.metamodel.Type;
/**
*
* @author Steve Ebersole
@ -432,36 +434,51 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
// otherwise, try to handle it as a polymorphic reference
{
EntityDomainType<T> polymorphicDomainType = (EntityDomainType<T>) polymorphicEntityReferenceMap.get( javaType );
final EntityDomainType<T> polymorphicDomainType = (EntityDomainType<T>) polymorphicEntityReferenceMap.get( javaType );
if ( polymorphicDomainType != null ) {
return polymorphicDomainType;
}
// create a set of descriptors that should be used to build the polymorphic EntityDomainType
final Set<EntityDomainType<?>> matchingDescriptors = new HashSet<>();
for ( EntityDomainType<?> entityDomainType : jpaEntityTypeMap.values() ) {
// see if we should add `entityDomainType` as one of the matching-descriptors.
if ( javaType.isAssignableFrom( entityDomainType.getJavaType() ) ) {
// the queried type is assignable from the type of the current entity-type
// we should add it to the collecting set of matching descriptors. it should
// be added aside from a few cases...
// it should not be added if its direct super (if one) is defined without
// explicit-polymorphism. The super itself will get added and the initializers
// for entity mappings already handle loading subtypes - adding it would be redundant
final ManagedDomainType<?> superType = entityDomainType.getSuperType();
// If the entity super type is also assignable, skip adding this entity type
if ( superType instanceof EntityDomainType<?>
if ( superType != null
&& superType.getPersistenceType() == Type.PersistenceType.ENTITY
&& javaType.isAssignableFrom( superType.getJavaType() ) ) {
final Queryable entityPersister = (Queryable) typeConfiguration.getSessionFactory()
final EntityMappingType superMapping = typeConfiguration.getSessionFactory()
.getRuntimeMetamodels()
.getMappingMetamodel()
.getEntityDescriptor( ( (EntityDomainType<?>) superType ).getHibernateEntityName() );
// But only skip adding this type if the parent doesn't require explicit polymorphism
if ( !entityPersister.isExplicitPolymorphism() ) {
if ( !superMapping.isExplicitPolymorphism() ) {
continue;
}
}
final Queryable entityPersister = (Queryable) typeConfiguration.getSessionFactory()
// it should not be added if it is mapped with explicit polymorphism itself
final EntityMappingType entityPersister = typeConfiguration.getSessionFactory()
.getRuntimeMetamodels()
.getMappingMetamodel()
.getEntityDescriptor( entityDomainType.getHibernateEntityName() );
if ( !entityPersister.isExplicitPolymorphism() ) {
matchingDescriptors.add( entityDomainType );
if ( entityPersister.isExplicitPolymorphism() ) {
continue;
}
// aside from these special cases, add it
matchingDescriptors.add( entityDomainType );
}
}
// if we found any matching, create the virtual root EntityDomainType reference
if ( !matchingDescriptors.isEmpty() ) {
final SqmPolymorphicRootDescriptor<T> descriptor = new SqmPolymorphicRootDescriptor<>(
typeConfiguration.getJavaTypeRegistry().resolveDescriptor( javaType ),

View File

@ -18,9 +18,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import jakarta.persistence.metamodel.EmbeddableType;
import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.ManagedType;
import org.hibernate.EntityNameResolver;
import org.hibernate.HibernateException;
@ -50,6 +47,7 @@ import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.internal.JpaMetaModelPopulationSetting;
import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
import org.hibernate.metamodel.model.domain.BasicDomainType;
@ -68,10 +66,10 @@ import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.persister.spi.PersisterFactory;
import org.hibernate.query.BindableType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral;
import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.type.BasicType;
import org.hibernate.type.ComponentType;
@ -81,6 +79,10 @@ import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.metamodel.EmbeddableType;
import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.ManagedType;
import static org.hibernate.metamodel.internal.JpaMetaModelPopulationSetting.determineJpaMetaModelPopulationSetting;
import static org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting.determineJpaStaticMetaModelPopulationSetting;
@ -750,10 +752,9 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo
ArrayList<String> results = new ArrayList<>();
for ( EntityPersister checkPersister : entityPersisters().values() ) {
if ( checkPersister instanceof Queryable ) {
final Queryable checkQueryable = (Queryable) checkPersister;
final String checkQueryableEntityName = checkQueryable.getEntityName();
final String checkQueryableEntityName = ((EntityMappingType) checkPersister).getEntityName();
final boolean isMappedClass = clazz.getName().equals( checkQueryableEntityName );
if ( checkQueryable.isExplicitPolymorphism() ) {
if ( checkPersister.isExplicitPolymorphism() ) {
if ( isMappedClass ) {
return new String[] { clazz.getName() }; // NOTE EARLY EXIT
}
@ -763,11 +764,12 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo
results.add( checkQueryableEntityName );
}
else {
final Class<?> mappedClass = checkQueryable.getMappedClass();
final Class<?> mappedClass = checkPersister.getMappedClass();
if ( mappedClass != null && clazz.isAssignableFrom( mappedClass ) ) {
final boolean assignableSuperclass;
if ( checkQueryable.isInherited() ) {
Class<?> mappedSuperclass = getEntityDescriptor( checkQueryable.getMappedSuperclass() ).getMappedClass();
if ( checkPersister.isInherited() ) {
final String superTypeName = checkPersister.getSuperMappingType().getEntityName();
Class<?> mappedSuperclass = getEntityDescriptor( superTypeName ).getMappedClass();
assignableSuperclass = clazz.isAssignableFrom( mappedSuperclass );
}
else {

View File

@ -14,9 +14,11 @@ import org.hibernate.type.Type;
/**
* @author Gavin King
*
* @deprecated Replaced by {@link org.hibernate.metamodel.mapping.internal.EmbeddedCollectionPart}
*/
@Deprecated( since = "6", forRemoval = true )
@Remove()
@Deprecated(since = "6", forRemoval = true)
@Remove
public class CompositeElementPropertyMapping extends AbstractPropertyMapping {
private final CompositeType compositeType;

View File

@ -13,9 +13,11 @@ import org.hibernate.type.Type;
/**
* @author Gavin King
*
* @deprecated Replaced by {@link org.hibernate.metamodel.mapping.CollectionPart}
*/
@Deprecated( since = "6", forRemoval = true )
@Remove()
@Deprecated(since = "6", forRemoval = true)
@Remove
public class ElementPropertyMapping implements PropertyMapping {
private final String[] elementColumns;

View File

@ -267,7 +267,6 @@ import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.tuple.NonIdentifierAttribute;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.type.AnyType;
import org.hibernate.type.AssociationType;
import org.hibernate.type.BasicType;
import org.hibernate.type.CollectionType;
import org.hibernate.type.CompositeType;
@ -871,7 +870,7 @@ public abstract class AbstractEntityPersister
}
public String getDiscriminatorColumnReaderTemplate() {
if ( getEntityMetamodel().getSubclassEntityNames().size() == 1 ) {
if ( getSubMappingTypes().size() == 1 ) {
return getDiscriminatorSQLValue();
}
else {
@ -2839,6 +2838,17 @@ public abstract class AbstractEntityPersister
insertCoordinator.coordinateInsert( id, fields, object, session );
}
protected EntityTableMapping[] getTableMappings() {
return tableMappings;
}
public int getTableMappingsCount() {
return tableMappings.length;
}
public EntityTableMapping getTableMapping(int i) {
return tableMappings[i];
}
/**
* Unfortunately we cannot directly use `SelectableMapping#getContainingTableExpression()`

View File

@ -38,9 +38,11 @@ import org.hibernate.type.Type;
* Basic implementation of the {@link PropertyMapping} contract.
*
* @author Gavin King
*
* @deprecated Replaced by {@link org.hibernate.metamodel.mapping.EntityMappingType}
*/
@Deprecated( since = "6", forRemoval = true )
@Remove()
@Deprecated(since = "6", forRemoval = true)
@Remove
public abstract class AbstractPropertyMapping implements PropertyMapping {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractPropertyMapping.class );

View File

@ -93,6 +93,7 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
else {
loadable = (Loadable) mappingMetamodel.getEntityDescriptor( (String) domainForm );
}
return loadable.getDiscriminatorValue();
}

View File

@ -27,6 +27,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.event.spi.EventSource;
import org.hibernate.generator.Generator;
import org.hibernate.generator.InMemoryGenerator;
import org.hibernate.generator.internal.VersionGeneration;
import org.hibernate.id.IdentifierGenerator;
@ -48,7 +49,6 @@ import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
import org.hibernate.sql.ast.spi.SqlAliasStemHelper;
import org.hibernate.sql.ast.tree.from.RootTableGroupProducer;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.generator.Generator;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.type.BasicType;
import org.hibernate.type.Type;
@ -396,6 +396,8 @@ public interface EntityPersister
*
* @return True if either (1) {@link #hasIdentifierProperty()} or
* (2) the identifier is an embedded composite identifier; false otherwise.
*
* @deprecated This feature is no longer supported
*/
@Deprecated(since = "6")
default boolean canExtractIdOutOfEntity() {

View File

@ -13,7 +13,13 @@ import org.hibernate.metamodel.mapping.Restrictable;
* persisters for classes or collections.
*
* @author Gavin King
*
* @deprecated Use {@link org.hibernate.metamodel.mapping.ModelPartContainer},
* {@link org.hibernate.sql.ast.tree.from.TableGroupProducer} and/or
* {@link org.hibernate.sql.ast.tree.from.TableGroupJoinProducer} instead
* depending on need
*/
@Deprecated(since = "6", forRemoval = true)
public interface Joinable extends Restrictable {
//should this interface extend PropertyMapping?

View File

@ -46,6 +46,7 @@ import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.EntityVersionMapping;
import org.hibernate.metamodel.mapping.TableDetails;
import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl;
import org.hibernate.metamodel.mapping.internal.CaseStatementDiscriminatorMappingImpl;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
@ -1282,6 +1283,20 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
return new DynamicFilterAliasGenerator(subclassTableNameClosure, rootAlias);
}
@Override
public TableDetails getMappedTableDetails() {
return getTableMapping( getTableMappings().length - 1 );
}
@Override
public TableDetails getIdentifierTableDetails() {
final EntityMappingType superMappingType = getSuperMappingType();
if ( superMappingType == null ) {
return getMappedTableDetails();
}
return superMappingType.getIdentifierTableDetails();
}
@Override
public <T> DomainResult<T> createDomainResult(
NavigablePath navigablePath,

View File

@ -12,7 +12,8 @@ package org.hibernate.persister.entity;
*
* @author Gavin King
*
* @deprecated See {@link org.hibernate.metamodel.mapping.ModelPartContainer}
* @deprecated Use {@link org.hibernate.metamodel.mapping.EntityMappingType}
* instead
*/
@Deprecated(since = "6.0")
public interface Queryable extends Loadable, PropertyMapping, Joinable {

View File

@ -39,6 +39,8 @@ import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.TableDetails;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.spi.PersisterCreationContext;
@ -518,6 +520,16 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
return discriminatorType;
}
@Override
public TableDetails getMappedTableDetails() {
return getTableMapping( 0 );
}
@Override
public TableDetails getIdentifierTableDetails() {
return getTableMapping( 0 );
}
@Override
public Object getDiscriminatorValue() {
return discriminatorValue;
@ -860,22 +872,22 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
.getRuntimeMetamodels()
.getMappingMetamodel();
for ( String subclass : treatedEntityNames ) {
final Queryable queryable = (Queryable) mappingMetamodel.getEntityDescriptor( subclass );
if ( !queryable.isAbstract() ) {
frag.addValue( queryable.getDiscriminatorSQLValue() );
final EntityMappingType treatTargetType = mappingMetamodel.getEntityDescriptor( subclass );
if ( !treatTargetType.isAbstract() ) {
frag.addValue( treatTargetType.getDiscriminatorSQLValue() );
}
if ( queryable.hasSubclasses() ) {
if ( treatTargetType.hasSubclasses() ) {
// if the treat is an abstract class, add the concrete implementations to values if any
Set<String> actualSubClasses = queryable.getSubclassEntityNames();
Set<String> actualSubClasses = treatTargetType.getSubclassEntityNames();
for ( String actualSubClass : actualSubClasses ) {
if ( actualSubClass.equals( subclass ) ) {
continue;
}
final Queryable actualQueryable = (Queryable) mappingMetamodel.getEntityDescriptor( actualSubClass );
if ( !actualQueryable.hasSubclasses() ) {
frag.addValue( actualQueryable.getDiscriminatorSQLValue() );
final EntityMappingType actualEntityDescriptor = mappingMetamodel.getEntityDescriptor( actualSubClass );
if ( !actualEntityDescriptor.hasSubclasses() ) {
frag.addValue( actualEntityDescriptor.getDiscriminatorSQLValue() );
}
}
}

View File

@ -44,6 +44,7 @@ import org.hibernate.mapping.Table;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.SelectableConsumer;
import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.TableDetails;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
@ -302,6 +303,16 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
return discriminatorType;
}
@Override
public TableDetails getMappedTableDetails() {
return getTableMapping( 0 );
}
@Override
public TableDetails getIdentifierTableDetails() {
return getTableMapping( 0 );
}
@Override
public Object getDiscriminatorValue() {
return discriminatorValue;

View File

@ -36,6 +36,7 @@ import org.hibernate.metamodel.mapping.NaturalIdMapping;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.SelectableConsumer;
import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.TableDetails;
import org.hibernate.metamodel.mapping.internal.OneToManyCollectionPart;
import org.hibernate.metamodel.mapping.internal.SingleAttributeIdentifierMapping;
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
@ -568,6 +569,11 @@ public class AnonymousTupleEntityValuedModelPart
return delegate.forEachJdbcValue( value, clause, offset, consumer, session );
}
@Override
public boolean isExplicitPolymorphism() {
return false;
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
return delegate.forEachJdbcType( offset, action );
@ -583,6 +589,16 @@ public class AnonymousTupleEntityValuedModelPart
return delegate.getEntityMappingType().getEntityName();
}
@Override
public TableDetails getMappedTableDetails() {
return delegate.getEntityMappingType().getMappedTableDetails();
}
@Override
public TableDetails getIdentifierTableDetails() {
return delegate.getEntityMappingType().getIdentifierTableDetails();
}
@Override
public void visitQuerySpaces(Consumer<String> querySpaceConsumer) {
delegate.getEntityMappingType().visitQuerySpaces( querySpaceConsumer );
@ -618,6 +634,11 @@ public class AnonymousTupleEntityValuedModelPart
return delegate.getEntityMappingType().getDiscriminatorValue();
}
@Override
public String getDiscriminatorSQLValue() {
return delegate.getEntityMappingType().getDiscriminatorSQLValue();
}
@Override
public String getSubclassForDiscriminatorValue(Object value) {
return delegate.getEntityMappingType().getSubclassForDiscriminatorValue( value );

View File

@ -20,6 +20,7 @@ import org.hibernate.dialect.temptable.TemporaryTableColumn;
import org.hibernate.dialect.temptable.TemporaryTableSessionUidColumn;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.Generator;
import org.hibernate.id.OptimizableGenerator;
import org.hibernate.id.enhanced.Optimizer;
import org.hibernate.internal.util.collections.CollectionHelper;
@ -52,7 +53,6 @@ import org.hibernate.sql.ast.tree.update.Assignment;
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.results.internal.SqlSelectionImpl;
import org.hibernate.generator.Generator;
import org.hibernate.type.BasicType;
import org.jboss.logging.Logger;

View File

@ -208,14 +208,12 @@ public class TableBasedUpdateHandler
}
return new UpdateExecutionDelegate(
getSqmUpdate(),
converterDelegate,
idTable,
afterUseAction,
sessionUidAccess,
domainParameterXref,
updatingTableGroup,
hierarchyRootTableReference,
tableReferenceByAlias,
assignments,
predicateCollector.getPredicate(),

View File

@ -34,7 +34,6 @@ import org.hibernate.query.sqm.mutation.internal.MultiTableSqmMutationConverter;
import org.hibernate.query.sqm.mutation.internal.TableKeyExpressionCollector;
import org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess;
import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression;
@ -64,12 +63,10 @@ import org.hibernate.sql.results.internal.SqlSelectionImpl;
* @author Steve Ebersole
*/
public class UpdateExecutionDelegate implements TableBasedUpdateHandler.ExecutionDelegate {
private final SqmUpdateStatement<?> sqmUpdate;
private final MultiTableSqmMutationConverter sqmConverter;
private final TemporaryTable idTable;
private final AfterUseAction afterUseAction;
private final Function<SharedSessionContractImplementor, String> sessionUidAccess;
private final DomainParameterXref domainParameterXref;
private final TableGroup updatingTableGroup;
private final Predicate suppliedPredicate;
@ -78,33 +75,27 @@ public class UpdateExecutionDelegate implements TableBasedUpdateHandler.Executio
private final JdbcParameterBindings jdbcParameterBindings;
private final Map<TableReference, List<Assignment>> assignmentsByTable;
private final Map<SqmParameter<?>, MappingModelExpressible<?>> paramTypeResolutions;
private final SessionFactoryImplementor sessionFactory;
public UpdateExecutionDelegate(
SqmUpdateStatement<?> sqmUpdate,
MultiTableSqmMutationConverter sqmConverter,
TemporaryTable idTable,
AfterUseAction afterUseAction,
Function<SharedSessionContractImplementor, String> sessionUidAccess,
DomainParameterXref domainParameterXref,
TableGroup updatingTableGroup,
TableReference hierarchyRootTableReference,
Map<String, TableReference> tableReferenceByAlias,
List<Assignment> assignments,
Predicate suppliedPredicate,
Map<SqmParameter<?>, List<List<JdbcParameter>>> parameterResolutions,
Map<SqmParameter<?>, MappingModelExpressible<?>> paramTypeResolutions,
DomainQueryExecutionContext executionContext) {
this.sqmUpdate = sqmUpdate;
this.sqmConverter = sqmConverter;
this.idTable = idTable;
this.afterUseAction = afterUseAction;
this.sessionUidAccess = sessionUidAccess;
this.domainParameterXref = domainParameterXref;
this.updatingTableGroup = updatingTableGroup;
this.suppliedPredicate = suppliedPredicate;
this.paramTypeResolutions = paramTypeResolutions;
this.sessionFactory = executionContext.getSession().getFactory();

View File

@ -12,6 +12,7 @@ import java.util.Map;
import org.hibernate.Internal;
import org.hibernate.dialect.Dialect;
import org.hibernate.metamodel.mapping.ModelPart;
/**
* An SQL {@code UPDATE} statement
@ -69,6 +70,13 @@ public class Update {
}
return this;
}
public Update addPrimaryKeyColumns(ModelPart keyPart) {
keyPart.forEachSelectable( (selectionIndex, selectableMapping) -> {
addPrimaryKeyColumn( selectableMapping.getSelectionExpression(), "?" );
} );
return this;
}
public Update addPrimaryKeyColumns(String[] columnNames, boolean[] includeColumns, String[] valueExpressions) {
for ( int i=0; i<columnNames.length; i++ ) {

View File

@ -43,6 +43,7 @@ import org.hibernate.internal.util.collections.Stack;
import org.hibernate.internal.util.collections.StandardStack;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.ModelPartContainer;
@ -50,9 +51,7 @@ import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.SqlExpressible;
import org.hibernate.metamodel.mapping.SqlTypedMapping;
import org.hibernate.persister.entity.AbstractEntityPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Loadable;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.persister.internal.SqlFragmentPredicate;
import org.hibernate.query.IllegalQueryOperationException;
import org.hibernate.query.ReturnableType;
@ -6280,8 +6279,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
@Override
public void visitEntityTypeLiteral(EntityTypeLiteral expression) {
final EntityPersister entityTypeDescriptor = expression.getEntityTypeDescriptor();
appendSql( (( Queryable ) entityTypeDescriptor).getDiscriminatorSQLValue() );
final EntityMappingType entityMapping = expression.getEntityTypeDescriptor();
appendSql( entityMapping.getDiscriminatorSQLValue() );
}
@Override

View File

@ -28,9 +28,10 @@ import org.hibernate.type.descriptor.java.JavaTypedExpressible;
/**
* @author Steve Ebersole
*/
public class EntityTypeLiteral implements Expression, MappingModelExpressible, DomainResultProducer, JavaTypedExpressible {
public class EntityTypeLiteral
implements Expression, MappingModelExpressible<Object>, DomainResultProducer<Object>, JavaTypedExpressible<Object> {
private final EntityPersister entityTypeDescriptor;
private final DiscriminatorType discriminatorType;
private final DiscriminatorType<?> discriminatorType;
public EntityTypeLiteral(EntityPersister entityTypeDescriptor) {
this.entityTypeDescriptor = entityTypeDescriptor;
@ -99,24 +100,21 @@ public class EntityTypeLiteral implements Expression, MappingModelExpressible, D
}
@Override
public DomainResult createDomainResult(String resultVariable, DomainResultCreationState creationState) {
return new BasicResult(
createSqlSelection( creationState )
.getValuesArrayPosition(),
public DomainResult<Object> createDomainResult(String resultVariable, DomainResultCreationState creationState) {
return new BasicResult<>(
createSqlSelection( creationState ).getValuesArrayPosition(),
resultVariable,
discriminatorType
);
}
private SqlSelection createSqlSelection(DomainResultCreationState creationState) {
return creationState.getSqlAstCreationState().getSqlExpressionResolver()
.resolveSqlSelection(
this,
discriminatorType.getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext()
.getMappingMetamodel().getTypeConfiguration()
);
return creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this,
discriminatorType.getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
);
}
@Override

View File

@ -7,13 +7,17 @@
package org.hibernate.sql.model;
import org.hibernate.jdbc.Expectation;
import org.hibernate.metamodel.mapping.TableDetails;
/**
* Describes a table as far as Hibernate understands it from mapping details
* <p/>
* Includes {@linkplain TableDetails basic details}, in addition to details
* about the table in relation to a particular {@link MutationTarget}
*
* @author Steve Ebersole
*/
public interface TableMapping {
public interface TableMapping extends TableDetails {
/**
* The name of the mapped table
*/

View File

@ -54,6 +54,7 @@ import org.hibernate.metamodel.mapping.EntityVersionMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.NaturalIdMapping;
import org.hibernate.metamodel.mapping.TableDetails;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
import org.hibernate.persister.collection.CollectionPersister;
@ -137,6 +138,16 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
return null;
}
@Override
public TableDetails getMappedTableDetails() {
throw new UnsupportedOperationException();
}
@Override
public TableDetails getIdentifierTableDetails() {
throw new UnsupportedOperationException();
}
@Override
public ModelPart findSubPart(
String name, EntityMappingType targetType) {
@ -193,6 +204,11 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
return 0;
}
@Override
public boolean isExplicitPolymorphism() {
return false;
}
@Override
public SqmMultiTableMutationStrategy getSqmMultiTableMutationStrategy() {
return null;

View File

@ -50,6 +50,7 @@ import org.hibernate.metamodel.mapping.EntityVersionMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.NaturalIdMapping;
import org.hibernate.metamodel.mapping.TableDetails;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
import org.hibernate.orm.test.jpa.SettingsGenerator;
@ -163,6 +164,16 @@ public class PersisterClassProviderTest {
return null;
}
@Override
public TableDetails getMappedTableDetails() {
throw new UnsupportedOperationException();
}
@Override
public TableDetails getIdentifierTableDetails() {
throw new UnsupportedOperationException();
}
@Override
public ModelPart findSubPart(
String name, EntityMappingType targetType) {
@ -219,6 +230,11 @@ public class PersisterClassProviderTest {
return 0;
}
@Override
public boolean isExplicitPolymorphism() {
return false;
}
@Override
public SqmMultiTableMutationStrategy getSqmMultiTableMutationStrategy() {
return null;

View File

@ -51,6 +51,7 @@ import org.hibernate.metamodel.mapping.EntityVersionMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.NaturalIdMapping;
import org.hibernate.metamodel.mapping.TableDetails;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
import org.hibernate.persister.entity.AttributeMappingsMap;
@ -124,6 +125,16 @@ public class CustomPersister implements EntityPersister {
return Custom.class.getName();
}
@Override
public TableDetails getMappedTableDetails() {
throw new UnsupportedOperationException();
}
@Override
public TableDetails getIdentifierTableDetails() {
throw new UnsupportedOperationException();
}
@Override
public ModelPart findSubPart(
String name, EntityMappingType targetType) {
@ -180,6 +191,11 @@ public class CustomPersister implements EntityPersister {
return 0;
}
@Override
public boolean isExplicitPolymorphism() {
throw new UnsupportedOperationException();
}
@Override
public SqmMultiTableMutationStrategy getSqmMultiTableMutationStrategy() {
return null;