diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityDiscriminatorMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityDiscriminatorMapping.java index 7c2b33a3fc..54cca6d339 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityDiscriminatorMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityDiscriminatorMapping.java @@ -9,8 +9,9 @@ package org.hibernate.metamodel.mapping; import org.hibernate.engine.FetchStyle; import org.hibernate.engine.FetchTiming; import org.hibernate.query.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.DomainResult; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.FetchOptions; @@ -40,6 +41,18 @@ public interface EntityDiscriminatorMapping extends VirtualModelPart, BasicValue String getConcreteEntityNameForDiscriminatorValue(Object value); + /** + * 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); + @Override BasicFetch generateFetch( FetchParent fetchParent, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java index fd3329ab83..2670c4e2c8 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java @@ -92,6 +92,10 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Inheritance + default boolean hasSubclasses() { + return getEntityPersister().getEntityMetamodel().hasSubclasses(); + } + default AttributeMapping findDeclaredAttributeMapping(String name) { throw new NotYetImplementedFor6Exception( getClass() ); // or ? @@ -144,16 +148,16 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel EntityIdentifierMapping getIdentifierMapping(); + EntityDiscriminatorMapping getDiscriminatorMapping(); + Object getDiscriminatorValue(); + String getSubclassForDiscriminatorValue(Object value); + EntityVersionMapping getVersionMapping(); - EntityRowIdMapping getRowIdMapping(); - - EntityDiscriminatorMapping getDiscriminatorMapping(); - - EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup); - NaturalIdMapping getNaturalIdMapping(); + EntityRowIdMapping getRowIdMapping(); + /** * Visit the mappings, but limited to just attributes defined * in the targetType or its super-type(s) if any. @@ -195,6 +199,10 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel return tableGroup.getPrimaryTableReference(); } + default boolean isAbstract() { + return getEntityPersister().getEntityMetamodel().isAbstract(); + } + interface ConstraintOrderedTableConsumer { void consume(String tableExpression, Supplier> tableKeyColumnVisitationSupplier); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractDiscriminatorMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractDiscriminatorMapping.java new file mode 100644 index 0000000000..6f582fb061 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractDiscriminatorMapping.java @@ -0,0 +1,397 @@ +/* + * 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 java.util.function.BiConsumer; +import java.util.function.Function; + +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; +import org.hibernate.engine.FetchTiming; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.mapping.IndexedConsumer; +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.convert.spi.BasicValueConverter; +import org.hibernate.metamodel.model.domain.NavigableRole; +import org.hibernate.persister.entity.DiscriminatorType; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlSelection; +import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.results.graph.DomainResult; +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.sql.results.graph.basic.BasicResult; +import org.hibernate.type.BasicType; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry; +import org.hibernate.type.spi.TypeConfiguration; + +import static org.hibernate.metamodel.RepresentationMode.MAP; + +/** + * @implNote `discriminatorType` represents the mapping to Class, whereas `discriminatorType.getUnderlyingType()` + * represents the "raw" JDBC mapping (String, Integer, etc) + * + * @author Steve Ebersole + */ +public abstract class AbstractDiscriminatorMapping implements EntityDiscriminatorMapping { + private final NavigableRole role; + private final JdbcMapping jdbcMapping; + + private final EntityPersister entityDescriptor; + private final DiscriminatorType discriminatorType; + private final SessionFactoryImplementor sessionFactory; + + private final DomainResultConverter domainResultConverter; + + public AbstractDiscriminatorMapping( + JdbcMapping jdbcMapping, + EntityPersister entityDescriptor, + DiscriminatorType discriminatorType, + MappingModelCreationProcess creationProcess) { + this.jdbcMapping = jdbcMapping; + + this.entityDescriptor = entityDescriptor; + this.discriminatorType = discriminatorType; + + role = entityDescriptor.getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME ); + sessionFactory = creationProcess.getCreationContext().getSessionFactory(); + + domainResultConverter = DomainResultConverter.create( + entityDescriptor, + this::getConcreteEntityNameForDiscriminatorValue, + discriminatorType.getUnderlyingType(), + sessionFactory + ); + } + + public EntityPersister getEntityDescriptor() { + return entityDescriptor; + } + + public BasicType getUnderlyingJdbcMappingType() { + return discriminatorType.getUnderlyingType(); + } + + public SessionFactoryImplementor getSessionFactory() { + return sessionFactory; + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // EntityDiscriminatorMapping + + @Override + public NavigableRole getNavigableRole() { + return role; + } + + @Override + public JdbcMapping getJdbcMapping() { + return jdbcMapping; + } + + @Override + public String getConcreteEntityNameForDiscriminatorValue(Object value) { + return getEntityDescriptor().getSubclassForDiscriminatorValue( value ); + } + + @Override + public EntityMappingType findContainingEntityMapping() { + return entityDescriptor; + } + + @Override + public MappingType getMappedType() { + return getJdbcMapping(); + } + + @Override + public JavaTypeDescriptor getJavaTypeDescriptor() { + return getJdbcMapping().getJavaTypeDescriptor(); + } + + @Override + public DomainResult createDomainResult( + NavigablePath navigablePath, + TableGroup tableGroup, + String resultVariable, + DomainResultCreationState creationState) { + final SqlSelection sqlSelection = resolveSqlSelection( navigablePath, getUnderlyingJdbcMappingType(), tableGroup, creationState.getSqlAstCreationState() ); + + //noinspection unchecked + return new BasicResult( + sqlSelection.getValuesArrayPosition(), + resultVariable, + domainResultConverter.getDomainJavaDescriptor(), + domainResultConverter, + navigablePath + ); + } + + private SqlSelection resolveSqlSelection( + NavigablePath navigablePath, + JdbcMapping jdbcMappingToUse, + TableGroup tableGroup, + SqlAstCreationState creationState) { + final SqlExpressionResolver expressionResolver = creationState.getSqlExpressionResolver(); + return expressionResolver.resolveSqlSelection( + resolveSqlExpression( navigablePath, jdbcMappingToUse, tableGroup, creationState ), + jdbcMappingToUse.getJavaTypeDescriptor(), + creationState.getCreationContext().getDomainModel().getTypeConfiguration() + ); + } + + @Override + public BasicFetch generateFetch( + FetchParent fetchParent, + NavigablePath fetchablePath, + FetchTiming fetchTiming, + boolean selected, + String resultVariable, + DomainResultCreationState creationState) { + final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState(); + final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup( + fetchParent.getNavigablePath() + ); + + assert tableGroup != null; + + final SqlSelection sqlSelection = resolveSqlSelection( fetchablePath, getUnderlyingJdbcMappingType(), tableGroup, creationState.getSqlAstCreationState() ); + + return new BasicFetch<>( + sqlSelection.getValuesArrayPosition(), + fetchParent, + fetchablePath, + this, + false, + null, + fetchTiming, + creationState + ); + } + + @Override + public void applySqlSelections( + NavigablePath navigablePath, + TableGroup tableGroup, + DomainResultCreationState creationState) { + resolveSqlSelection( navigablePath, getUnderlyingJdbcMappingType(), tableGroup, creationState.getSqlAstCreationState() ); + } + + @Override + public void applySqlSelections( + NavigablePath navigablePath, + TableGroup tableGroup, + DomainResultCreationState creationState, + BiConsumer selectionConsumer) { + selectionConsumer.accept( + resolveSqlSelection( navigablePath, getUnderlyingJdbcMappingType(), tableGroup, creationState.getSqlAstCreationState() ), + getJdbcMapping() + ); + } + + @Override + public int forEachDisassembledJdbcValue( + Object value, + Clause clause, + int offset, + JdbcValuesConsumer valuesConsumer, + SharedSessionContractImplementor session) { + valuesConsumer.consume( offset, convertToRelational( value ), getJdbcMapping() ); + return getJdbcTypeCount(); + } + + @Override + public int forEachJdbcType(int offset, IndexedConsumer action) { + action.accept( offset, getJdbcMapping() ); + return getJdbcTypeCount(); + } + + @Override + public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { + valueConsumer.consume( convertToRelational( domainValue ), this ); + } + + private Object convertToRelational(Object domainValue) { + if ( domainResultConverter != null ) { + return domainResultConverter.toRelationalValue( domainValue ); + } + return domainValue; + } + + @Override + public Object disassemble(Object value, SharedSessionContractImplementor session) { + return convertToRelational( value ); + } + + @Override + public int forEachJdbcValue(Object value, Clause clause, int offset, JdbcValuesConsumer valuesConsumer, SharedSessionContractImplementor session) { + valuesConsumer.consume( offset, convertToRelational( value ), jdbcMapping ); + return 1; + } + + @Override + public int forEachSelectable(SelectableConsumer consumer) { + return EntityDiscriminatorMapping.super.forEachSelectable( consumer ); + } + + @Override + public int forEachSelectable(int offset, SelectableConsumer consumer) { + return EntityDiscriminatorMapping.super.forEachSelectable( offset, consumer ); + } + + @Override + public int forEachJdbcType(IndexedConsumer action) { + return EntityDiscriminatorMapping.super.forEachJdbcType( action ); + } + + + + /** + * Used to convert the underlying discriminator value into a Class (or String for entity-name) + * reference for the entity type + */ + protected static class DomainResultConverter implements BasicValueConverter { + /** + * Given a "raw" discriminator value, determines the corresponding concrete entity name + */ + private final Function subtypeResolver; + + /** + * Given a concrete entity name, apply the conversion to determine the "domain result" value + * + * @apiNote This is only used when building a {@link DomainResult} + */ + private final Function entityNameHandler; + + /** + * Given a "domain form", apply the conversion to determine the corresponding relational value + */ + private final Function toRelationalConverter; + + private final JavaTypeDescriptor domainJtd; + private final JavaTypeDescriptor relationalJtd; + + public DomainResultConverter( + Function subtypeResolver, + Function entityNameHandler, + Function toRelationalConverter, + JavaTypeDescriptor domainJtd, + JavaTypeDescriptor relationalJtd) { + this.subtypeResolver = subtypeResolver; + this.entityNameHandler = entityNameHandler; + this.toRelationalConverter = toRelationalConverter; + this.domainJtd = domainJtd; + this.relationalJtd = relationalJtd; + } + + private static DomainResultConverter create( + EntityPersister entityDescriptor, + Function subtypeResolver, + BasicType underlyingDiscriminatorType, + final SessionFactoryImplementor sessionFactory) { + final TypeConfiguration typeConfiguration = sessionFactory.getDomainModel().getTypeConfiguration(); + final JavaTypeDescriptorRegistry jtdRegistry = typeConfiguration.getJavaTypeDescriptorRegistry(); + + final JavaTypeDescriptor domainJtd; + final Function entityNameHandler; + final Function toRelationalConverter; + + if ( entityDescriptor.getRepresentationStrategy().getMode() == MAP ) { + // todo (6.0) : account for explicit entity-name which should also return String + domainJtd = jtdRegistry.getDescriptor( String.class ); + entityNameHandler = (entityName) -> entityName; + toRelationalConverter = (domainValue) -> { + if ( domainValue instanceof Class ) { + throw new IllegalArgumentException( "Illegal attempt to specify Class for discriminator for dynamic entity" ); + } + if ( domainValue instanceof String ) { + final String stringValue = (String) domainValue; + // could be either an entity name or "underlying type" (e.g. mapped to VARCHAR) + // - first we check as an entity name since that's a discrete set; + // - handling as an "underlying type" value is handled in "otherwise" + if ( entityDescriptor.isSubclassEntityName( stringValue ) ) { + return entityDescriptor.getDiscriminatorValue(); + } + } + + // otherwise we assume its an instance of the underlying type + assert underlyingDiscriminatorType.getJavaTypeDescriptor().getJavaTypeClass().isInstance( domainJtd ); + return domainJtd; + }; + } + else { + final ClassLoaderService cls = sessionFactory.getServiceRegistry().getService( ClassLoaderService.class ); + domainJtd = jtdRegistry.getDescriptor( Class.class ); + entityNameHandler = cls::classForName; + toRelationalConverter = (domainValue) -> { + if ( domainValue instanceof Class ) { + final Class classValue = (Class) domainValue; + final EntityMappingType concreteEntityMapping = sessionFactory.getRuntimeMetamodels().getEntityMappingType( classValue ); + return concreteEntityMapping.getDiscriminatorValue(); + } + if ( domainValue instanceof String ) { + final String stringValue = (String) domainValue; + // could be either an entity name or "underlying type" (e.g. mapped to VARCHAR) + // - first we check as an entity name since that's a discrete set; + // - handling as an "underlying type" value is handled in "otherwise" + if ( entityDescriptor.isSubclassEntityName( stringValue ) ) { + return entityDescriptor.getDiscriminatorValue(); + } + } + + // otherwise we assume its an instance of the underlying type + assert underlyingDiscriminatorType.getJavaTypeDescriptor().getJavaTypeClass().isInstance( domainJtd ); + return domainJtd; + }; + } + + return new DomainResultConverter( + subtypeResolver, + entityNameHandler, + toRelationalConverter, + domainJtd, + underlyingDiscriminatorType.getJavaTypeDescriptor() + ); + } + + @Override + public Object toDomainValue(R relationalForm) { + final String entityName = subtypeResolver.apply( relationalForm ); + return entityNameHandler.apply( entityName ); + } + + @Override + public R toRelationalValue(Object domainForm) { + // the domainForm could be any of Class (entity type), String (entity-name) or + // underlying type (String, Integer, ..) + + return toRelationalConverter.apply( domainForm ); + } + + @Override + public JavaTypeDescriptor getDomainJavaDescriptor() { + return domainJtd; + } + + @Override + public JavaTypeDescriptor getRelationalJavaDescriptor() { + return relationalJtd; + } + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEntityDiscriminatorMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEntityDiscriminatorMapping.java deleted file mode 100644 index 72bc470aa8..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEntityDiscriminatorMapping.java +++ /dev/null @@ -1,152 +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.mapping.internal; - -import org.hibernate.engine.FetchTiming; -import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; -import org.hibernate.metamodel.mapping.JdbcMapping; -import org.hibernate.persister.entity.DiscriminatorType; -import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.persister.entity.Loadable; -import org.hibernate.query.NavigablePath; -import org.hibernate.sql.ast.spi.SqlAstCreationState; -import org.hibernate.sql.ast.spi.SqlSelection; -import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.results.graph.DomainResult; -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.sql.results.graph.basic.BasicResult; -import org.hibernate.type.descriptor.java.JavaTypeDescriptor; - -/** - * @author Andrea Boriero - */ -public abstract class AbstractEntityDiscriminatorMapping implements EntityDiscriminatorMapping { - private final EntityPersister entityDescriptor; - private final String tableExpression; - private final String mappedColumnExpression; - private final boolean isFormula; - - private final DiscriminatorType mappingType; - - public AbstractEntityDiscriminatorMapping( - EntityPersister entityDescriptor, - String tableExpression, - String mappedColumnExpression, - boolean isFormula, - DiscriminatorType mappingType) { - this.entityDescriptor = entityDescriptor; - this.tableExpression = tableExpression; - this.mappedColumnExpression = mappedColumnExpression; - this.isFormula = isFormula; - this.mappingType = mappingType; - } - - public EntityPersister getEntityDescriptor() { - return entityDescriptor; - } - - @Override - public String getContainingTableExpression() { - return tableExpression; - } - - @Override - public String getSelectionExpression() { - return mappedColumnExpression; - } - - @Override - public boolean isFormula() { - return isFormula; - } - - @Override - public String getConcreteEntityNameForDiscriminatorValue(Object value) { - return ( (Loadable) getEntityDescriptor() ).getSubclassForDiscriminatorValue( value ); - } - - @Override - public DomainResult createDomainResult( - NavigablePath navigablePath, - TableGroup tableGroup, - String resultVariable, - DomainResultCreationState creationState) { - final SqlSelection sqlSelection = resolveSqlSelection( tableGroup, false, creationState ); - - //noinspection unchecked - return new BasicResult( - sqlSelection.getValuesArrayPosition(), - resultVariable, - getJavaTypeDescriptor(), - navigablePath - ); - } - - @Override - public void applySqlSelections( - NavigablePath navigablePath, - TableGroup tableGroup, - DomainResultCreationState creationState) { - resolveSqlSelection( tableGroup, false, creationState ); - } - - @Override - public BasicFetch generateFetch( - FetchParent fetchParent, - NavigablePath fetchablePath, - FetchTiming fetchTiming, - boolean selected, - String resultVariable, - DomainResultCreationState creationState) { - final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState(); - final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup( - fetchParent.getNavigablePath() - ); - - assert tableGroup != null; - - final SqlSelection sqlSelection = resolveSqlSelection( tableGroup, true, creationState ); - - return new BasicFetch<>( - sqlSelection.getValuesArrayPosition(), - fetchParent, - fetchablePath, - this, - false, - null, - fetchTiming, - creationState - ); - } - - @Override - public JavaTypeDescriptor getJavaTypeDescriptor() { - return getMappedType().getMappedJavaTypeDescriptor(); - } - - @Override - public DiscriminatorType getMappedType() { - return mappingType; - } - - @Override - public DiscriminatorType getPartMappingType() { - return mappingType; - } - - @Override - public JdbcMapping getJdbcMapping() { - return mappingType.getJdbcMapping(); - } - - protected abstract SqlSelection resolveSqlSelection( - TableGroup tableGroup, - boolean underlyingType, - DomainResultCreationState creationState); -} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CaseStatementDiscriminatorMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CaseStatementDiscriminatorMappingImpl.java new file mode 100644 index 0000000000..85621a7762 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CaseStatementDiscriminatorMappingImpl.java @@ -0,0 +1,187 @@ +/* + * 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 java.util.LinkedHashMap; +import java.util.Map; + +import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; +import org.hibernate.metamodel.mapping.JdbcMapping; +import org.hibernate.persister.entity.DiscriminatorType; +import org.hibernate.persister.entity.JoinedSubclassEntityPersister; +import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression; +import org.hibernate.sql.ast.tree.expression.ColumnReference; +import org.hibernate.sql.ast.tree.expression.Expression; +import org.hibernate.sql.ast.tree.expression.QueryLiteral; +import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.predicate.NullnessPredicate; +import org.hibernate.sql.ast.tree.predicate.Predicate; + +import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey; + +/** + * @author Andrea Boriero + */ +public class CaseStatementDiscriminatorMappingImpl extends AbstractDiscriminatorMapping { + + private final LinkedHashMap tableDiscriminatorDetailsMap = new LinkedHashMap<>(); + + public CaseStatementDiscriminatorMappingImpl( + JoinedSubclassEntityPersister entityDescriptor, + String[] tableNames, + int[] notNullColumnTableNumbers, + String[] notNullColumnNames, + String[] discriminatorValues, + Map subEntityNameByTableName, + DiscriminatorType incomingDiscriminatorType, + MappingModelCreationProcess creationProcess) { + super( + incomingDiscriminatorType.getUnderlyingType().getJdbcMapping(), + entityDescriptor, + incomingDiscriminatorType, + creationProcess + ); + + for ( int i = 0; i < discriminatorValues.length; i++ ) { + final String tableName = tableNames[notNullColumnTableNumbers[i]]; + final String subEntityName = subEntityNameByTableName.get( tableName ); + final String oneSubEntityColumn = notNullColumnNames[i]; + + final String rawDiscriminatorValue = discriminatorValues[i]; + final Object discriminatorValue = getUnderlyingJdbcMappingType().getJavaTypeDescriptor().wrap( rawDiscriminatorValue, null ); + + tableDiscriminatorDetailsMap.put( + tableName, + new TableDiscriminatorDetails( + tableName, + oneSubEntityColumn, + discriminatorValue, + subEntityName + ) + ); + } + } + + @Override + public Expression resolveSqlExpression( + NavigablePath navigablePath, + JdbcMapping jdbcMappingToUse, + TableGroup tableGroup, + SqlAstCreationState creationState) { + final SqlExpressionResolver expressionResolver = creationState.getSqlExpressionResolver(); + return expressionResolver.resolveSqlExpression( + createColumnReferenceKey( tableGroup.getGroupAlias(), EntityDiscriminatorMapping.ROLE_NAME ), + sqlAstProcessingState -> createCaseSearchedExpression( tableGroup ) + ); + } + + private CaseSearchedExpression createCaseSearchedExpression(TableGroup entityTableGroup) { + final CaseSearchedExpression caseSearchedExpression = new CaseSearchedExpression( this ); + + tableDiscriminatorDetailsMap.forEach( (tableName, tableDiscriminatorDetails) -> { + TableReference tableReference; + try { + tableReference = entityTableGroup.resolveTableReference( entityTableGroup.getNavigablePath(), tableName ); + } + catch (Exception e) { + tableReference = null; + } + + if ( tableReference == null ) { + // assume this is because it is a table that is not part of the processing entity's sub-hierarchy + return; + } + + final Predicate predicate = new NullnessPredicate( + new ColumnReference( + tableReference, + tableDiscriminatorDetails.getCheckColumnName(), + false, + null, + null, + getJdbcMapping(), + getSessionFactory() + ), + true + ); + + caseSearchedExpression.when( predicate, new QueryLiteral<>( + tableDiscriminatorDetails.getDiscriminatorValue(), + getUnderlyingJdbcMappingType() + ) ); + } ); + + return caseSearchedExpression; + } + + @Override + public String getCustomReadExpression() { + return null; + } + + @Override + public String getCustomWriteExpression() { + return null; + } + + @Override + public String getContainingTableExpression() { + throw new UnsupportedOperationException(); +// // this *should* only be used to create the sql-expression key, so just +// // using the primary table expr should be fine +// return entityDescriptor.getRootTableName(); + } + + @Override + public String getSelectionExpression() { + throw new UnsupportedOperationException(); +// // this *should* only be used to create the sql-expression key, so just +// // using the ROLE_NAME should be fine +// return ROLE_NAME; + } + + + @Override + public boolean isFormula() { + return false; + } + + private static class TableDiscriminatorDetails { + 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) { + 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; + } + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityDiscriminatorMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityDiscriminatorMappingImpl.java deleted file mode 100644 index 16546f9654..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityDiscriminatorMappingImpl.java +++ /dev/null @@ -1,121 +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.mapping.internal; - -import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.mapping.IndexedConsumer; -import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; -import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.metamodel.mapping.JdbcMapping; -import org.hibernate.metamodel.model.domain.NavigableRole; -import org.hibernate.persister.entity.DiscriminatorType; -import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.sql.ast.Clause; -import org.hibernate.sql.ast.spi.SqlExpressionResolver; -import org.hibernate.sql.ast.spi.SqlSelection; -import org.hibernate.sql.ast.tree.expression.ColumnReference; -import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableReference; -import org.hibernate.sql.results.graph.DomainResultCreationState; -import org.hibernate.type.BasicType; - -/** - * @author Steve Ebersole - */ -public class EntityDiscriminatorMappingImpl extends AbstractEntityDiscriminatorMapping { - private final NavigableRole navigableRole; - - public EntityDiscriminatorMappingImpl( - EntityPersister entityDescriptor, - String tableExpression, - String mappedColumnExpression, - boolean isFormula, - DiscriminatorType mappingType) { - super( entityDescriptor, tableExpression, mappedColumnExpression, isFormula, mappingType ); - this.navigableRole = entityDescriptor.getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME ); - } - - @Override - protected SqlSelection resolveSqlSelection( - TableGroup tableGroup, - boolean underlyingType, - DomainResultCreationState creationState) { - final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState() - .getSqlExpressionResolver(); - - final TableReference tableReference = tableGroup.resolveTableReference( - tableGroup.getNavigablePath() - .append( getNavigableRole().getNavigableName() ), - getContainingTableExpression() - ); - final BasicType type = underlyingType ? getMappedType().getUnderlyingType() : getMappedType(); - - return expressionResolver.resolveSqlSelection( - expressionResolver.resolveSqlExpression( - SqlExpressionResolver.createColumnReferenceKey( - tableReference, - getSelectionExpression() - ), - sqlAstProcessingState -> new ColumnReference( - tableReference.getIdentificationVariable(), - this, - type, - creationState.getSqlAstCreationState().getCreationContext().getSessionFactory() - ) - ), - type.getMappedJavaTypeDescriptor(), - creationState.getSqlAstCreationState().getCreationContext().getDomainModel().getTypeConfiguration() - ); - } - - @Override - public int forEachDisassembledJdbcValue( - Object value, - Clause clause, - int offset, - JdbcValuesConsumer valuesConsumer, - SharedSessionContractImplementor session) { - valuesConsumer.consume( offset, value, getJdbcMapping() ); - return getJdbcTypeCount(); - } - - @Override - public int forEachJdbcType(int offset, IndexedConsumer action) { - action.accept( offset, getJdbcMapping() ); - return getJdbcTypeCount(); - } - - @Override - public Object disassemble(Object value, SharedSessionContractImplementor session) { - return value; - } - - @Override - public NavigableRole getNavigableRole() { - return navigableRole; - } - - @Override - public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { - valueConsumer.consume( domainValue, this ); - } - - @Override - public EntityMappingType findContainingEntityMapping() { - return getEntityDescriptor(); - } - - @Override - public String getCustomReadExpression() { - return null; - } - - @Override - public String getCustomWriteExpression() { - return null; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ExplicitColumnDiscriminatorMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ExplicitColumnDiscriminatorMappingImpl.java new file mode 100644 index 0000000000..0df0f9a6d6 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ExplicitColumnDiscriminatorMappingImpl.java @@ -0,0 +1,99 @@ +/* + * 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.EntityDiscriminatorMapping; +import org.hibernate.metamodel.mapping.JdbcMapping; +import org.hibernate.persister.entity.DiscriminatorType; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.spi.SqlAstCreationState; +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; + +import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey; + +/** + * @author Steve Ebersole + */ +public class ExplicitColumnDiscriminatorMappingImpl extends AbstractDiscriminatorMapping { + private final String tableExpression; + private final String columnName; + private final String columnFormula; + + public ExplicitColumnDiscriminatorMappingImpl( + EntityPersister entityDescriptor, + DiscriminatorType discriminatorType, + String tableExpression, + String columnExpression, + boolean isFormula, + MappingModelCreationProcess creationProcess) { + super( discriminatorType.getJdbcMapping(), entityDescriptor, discriminatorType, creationProcess ); + this.tableExpression = tableExpression; + if ( isFormula ) { + columnName = null; + columnFormula = columnExpression; + } + else { + columnName = columnExpression; + columnFormula = null; + } + } + + @Override + public Expression resolveSqlExpression( + NavigablePath navigablePath, + JdbcMapping jdbcMappingToUse, + TableGroup tableGroup, + SqlAstCreationState creationState) { + final SqlExpressionResolver expressionResolver = creationState.getSqlExpressionResolver(); + + final TableReference tableReference = tableGroup.resolveTableReference( navigablePath, tableExpression ); + + return expressionResolver.resolveSqlExpression( + createColumnReferenceKey( tableReference, EntityDiscriminatorMapping.ROLE_NAME ), + sqlAstProcessingState -> new ColumnReference( + tableReference, + columnFormula == null ? columnName : columnFormula, + columnFormula != null, + null, + null, + jdbcMappingToUse, + getSessionFactory() + + ) + ); + } + + @Override + public String getContainingTableExpression() { + return tableExpression; + } + + @Override + public String getSelectionExpression() { + return columnName == null ? columnFormula : columnName; + } + + @Override + public String getCustomReadExpression() { + return null; + } + + @Override + public String getCustomWriteExpression() { + return null; + } + + @Override + public boolean isFormula() { + return columnFormula != null; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/JoinedSubclassDiscriminatorMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/JoinedSubclassDiscriminatorMappingImpl.java deleted file mode 100644 index b368febc8b..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/JoinedSubclassDiscriminatorMappingImpl.java +++ /dev/null @@ -1,104 +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.mapping.internal; - -import java.util.List; - -import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.mapping.IndexedConsumer; -import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; -import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.metamodel.mapping.JdbcMapping; -import org.hibernate.metamodel.model.domain.NavigableRole; -import org.hibernate.persister.entity.DiscriminatorType; -import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.sql.ast.spi.SqlExpressionResolver; -import org.hibernate.sql.ast.spi.SqlSelection; -import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression; -import org.hibernate.sql.ast.tree.expression.ColumnReference; -import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.results.graph.DomainResultCreationState; -import org.hibernate.type.BasicType; - -/** - * @author Andrea Boriero - */ -public class JoinedSubclassDiscriminatorMappingImpl extends AbstractEntityDiscriminatorMapping { - private final NavigableRole navigableRole; - private final CaseSearchedExpression caseSearchedExpression; - private final CaseSearchedExpression caseSearchedExpressionUnderlying; - - public JoinedSubclassDiscriminatorMappingImpl( - EntityPersister entityDescriptor, - String tableExpression, - String mappedColumnExpression, - boolean isFormula, - CaseSearchedExpression caseSearchedExpression, - List columnReferences, - DiscriminatorType mappingType) { - super( entityDescriptor, tableExpression, mappedColumnExpression, isFormula, mappingType ); - - this.navigableRole = entityDescriptor.getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME ); - this.caseSearchedExpression = caseSearchedExpression; - final CaseSearchedExpression caseSearchedExpressionUnderlying = new CaseSearchedExpression( mappingType.getUnderlyingType() ); - for ( CaseSearchedExpression.WhenFragment whenFragment : caseSearchedExpression.getWhenFragments() ) { - caseSearchedExpressionUnderlying.when( whenFragment.getPredicate(), whenFragment.getResult() ); - } - caseSearchedExpressionUnderlying.otherwise( caseSearchedExpression.getOtherwise() ); - this.caseSearchedExpressionUnderlying = caseSearchedExpressionUnderlying; - } - - @Override - protected SqlSelection resolveSqlSelection( - TableGroup tableGroup, - boolean underlyingType, - DomainResultCreationState creationState) { - final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState() - .getSqlExpressionResolver(); - final BasicType type = underlyingType ? getMappedType().getUnderlyingType() : getMappedType(); - - return expressionResolver.resolveSqlSelection( - expressionResolver.resolveSqlExpression( - getSelectionExpression(), - sqlAstProcessingState -> underlyingType ? caseSearchedExpressionUnderlying : caseSearchedExpression - ), - type.getMappedJavaTypeDescriptor(), - creationState.getSqlAstCreationState().getCreationContext().getDomainModel().getTypeConfiguration() - ); - } - - @Override - public NavigableRole getNavigableRole() { - return navigableRole; - } - - @Override - public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { - valueConsumer.consume( domainValue, this ); - } - - @Override - public EntityMappingType findContainingEntityMapping() { - return getEntityDescriptor(); - } - - @Override - public String getCustomReadExpression() { - return null; - } - - @Override - public String getCustomWriteExpression() { - return null; - } - - @Override - public int forEachJdbcType(int offset, IndexedConsumer action) { - action.accept( offset, getJdbcMapping() ); - return getJdbcTypeCount(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DiscriminatorSqmPath.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DiscriminatorSqmPath.java new file mode 100644 index 0000000000..a5e1c93903 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DiscriminatorSqmPath.java @@ -0,0 +1,92 @@ +/* + * 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.mapping.EntityDiscriminatorMapping; +import org.hibernate.metamodel.mapping.EntityMappingType; +import org.hibernate.metamodel.mapping.EntityValuedModelPart; +import org.hibernate.metamodel.model.domain.EntityDomainType; +import org.hibernate.query.PathException; +import org.hibernate.query.hql.spi.SemanticPathPart; +import org.hibernate.query.hql.spi.SqmCreationState; +import org.hibernate.query.sqm.IllegalPathUsageException; +import org.hibernate.query.sqm.NodeBuilder; +import org.hibernate.query.sqm.SemanticQueryWalker; +import org.hibernate.query.sqm.SqmPathSource; +import org.hibernate.query.sqm.sql.internal.DiscriminatorPathInterpretation; +import org.hibernate.query.sqm.sql.internal.SelfInterpretingSqmPath; +import org.hibernate.query.sqm.sql.internal.SqmPathInterpretation; +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.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.tree.from.TableGroup; + +/** + * SqmPath specialization for an entity discriminator + * + * @author Steve Ebersole + */ +@SuppressWarnings({ "rawtypes", "unchecked" }) +public class DiscriminatorSqmPath extends AbstractSqmPath implements SelfInterpretingSqmPath { + private final EntityDomainType entityDomainType; + private final EntityMappingType entityDescriptor; + + protected DiscriminatorSqmPath( + SqmPathSource referencedPathSource, + SqmPath lhs, + EntityDomainType entityDomainType, + EntityMappingType entityDescriptor, + NodeBuilder nodeBuilder) { + super( lhs.getNavigablePath().append( EntityDiscriminatorMapping.ROLE_NAME ), referencedPathSource, lhs, nodeBuilder ); + this.entityDomainType = entityDomainType; + this.entityDescriptor = entityDescriptor; + } + + @Override + public X accept(SemanticQueryWalker walker) { + if ( ! entityDescriptor.hasSubclasses() ) { + return walker.visitEntityTypeLiteralExpression( new SqmLiteralEntityType( entityDomainType, nodeBuilder() ) ); + } + + return walker.visitSelfInterpretingSqmPath( this ); + } + + @Override + public SqmPathInterpretation interpret( + SqlAstCreationState sqlAstCreationState, + SemanticQueryWalker sqmWalker, + boolean jpaQueryComplianceEnabled) { + assert entityDescriptor.hasSubclasses(); + + final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup( getLhs().getNavigablePath() ); + final EntityMappingType entityMapping = ( (EntityValuedModelPart) tableGroup.getModelPart() ).getEntityMappingType(); + + return new DiscriminatorPathInterpretation( getNavigablePath(), entityMapping, tableGroup, sqlAstCreationState ); + } + + @Override + public void appendHqlString(StringBuilder sb) { + // todo (6.0) : no idea + } + + @Override + public SemanticPathPart resolvePathPart(String name, boolean isTerminal, SqmCreationState creationState) { + throw new IllegalPathUsageException( "Discriminator cannot be de-referenced" ); + } + + @Override + public SqmTreatedPath treatAs(Class treatJavaType) throws PathException { + throw new UnsupportedOperationException( "Cannot apply TREAT operator to discriminator path" ); + } + + @Override + public SqmTreatedPath treatAs(EntityDomainType treatTarget) throws PathException { + throw new UnsupportedOperationException( "Cannot apply TREAT operator to discriminator path" ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DiscriminatorSqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DiscriminatorSqmPathSource.java new file mode 100644 index 0000000000..fa11bef3a6 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DiscriminatorSqmPathSource.java @@ -0,0 +1,44 @@ +/* + * 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.mapping.EntityDiscriminatorMapping; +import org.hibernate.metamodel.mapping.EntityMappingType; +import org.hibernate.metamodel.model.domain.DomainType; +import org.hibernate.metamodel.model.domain.EntityDomainType; +import org.hibernate.query.sqm.IllegalPathUsageException; +import org.hibernate.query.sqm.SqmPathSource; +import org.hibernate.query.sqm.tree.domain.SqmPath; + +/** + * SqmPathSource implementation for entity discriminator + * + * @author Steve Ebersole + */ +public class DiscriminatorSqmPathSource extends AbstractSqmPathSource { + private final EntityDomainType entityDomainType; + private final EntityMappingType entityMapping; + + public DiscriminatorSqmPathSource( + DomainType discriminatorValueType, + EntityDomainType entityDomainType, + EntityMappingType entityMapping) { + super( EntityDiscriminatorMapping.ROLE_NAME, discriminatorValueType, BindableType.SINGULAR_ATTRIBUTE ); + this.entityDomainType = entityDomainType; + this.entityMapping = entityMapping; + } + + @Override + public SqmPath createSqmPath(SqmPath lhs) { + return new DiscriminatorSqmPath( this, lhs, entityDomainType, entityMapping, lhs.nodeBuilder() ); + } + + @Override + public SqmPathSource findSubPathSource(String name) throws IllegalPathUsageException { + throw new IllegalPathUsageException( "Entity discriminator cannot be de-referenced" ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntityTypeImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntityTypeImpl.java index 0c387c23aa..a98ffabf71 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntityTypeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntityTypeImpl.java @@ -22,10 +22,7 @@ import org.hibernate.metamodel.model.domain.PersistentAttribute; import org.hibernate.metamodel.model.domain.SingularPersistentAttribute; import org.hibernate.persister.entity.DiscriminatorMetadata; import org.hibernate.persister.entity.Queryable; -import org.hibernate.query.sqm.IllegalPathUsageException; import org.hibernate.query.sqm.SqmPathSource; -import org.hibernate.query.sqm.tree.domain.SqmBasicValuedEntityTypePath; -import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; @@ -71,59 +68,12 @@ public class EntityTypeImpl else { discriminatorType = StandardBasicTypes.STRING; } - final boolean hasSubclasses = persistentClass.hasSubclasses(); - this.discriminatorPathSource = new SqmPathSource() { - @Override - public String getPathName() { - return EntityDiscriminatorMapping.ROLE_NAME; - } - @Override - public DomainType getSqmPathType() { - // the BasicType for Class? - return discriminatorType; - } - - @Override - public SqmPathSource findSubPathSource(String name) { - throw new IllegalPathUsageException( "Entity discriminator cannot be de-referenced" ); - } - - @Override - public SqmPath createSqmPath(SqmPath lhs) { - if ( hasSubclasses ) { - return new SqmBasicValuedSimplePath<>( - lhs.getNavigablePath().append( EntityDiscriminatorMapping.ROLE_NAME ), - this, - lhs, - lhs.nodeBuilder() - ); - } - else { - return new SqmBasicValuedEntityTypePath<>( - lhs.getNavigablePath().append( EntityDiscriminatorMapping.ROLE_NAME ), - EntityTypeImpl.this, - lhs, - lhs.nodeBuilder() - ); - } - } - - @Override - public BindableType getBindableType() { - return BindableType.SINGULAR_ATTRIBUTE; - } - - @Override - public Class getBindableJavaType() { - return getExpressableJavaTypeDescriptor().getJavaTypeClass(); - } - - @Override - public JavaTypeDescriptor getExpressableJavaTypeDescriptor() { - return discriminatorType.getExpressableJavaTypeDescriptor(); - } - }; + this.discriminatorPathSource = new DiscriminatorSqmPathSource<>( + discriminatorType, + this, + entityPersister + ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 3fad50f808..1d0ea7ab4d 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -107,7 +107,6 @@ import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.FilterHelper; -import org.hibernate.internal.util.MutableBoolean; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.CollectionHelper; @@ -167,9 +166,9 @@ 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.EmbeddedAttributeMapping; -import org.hibernate.metamodel.mapping.internal.EntityDiscriminatorMappingImpl; 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.InFlightEntityMappingType; import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper; @@ -208,7 +207,6 @@ import org.hibernate.sql.Update; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstJoinType; import org.hibernate.sql.ast.spi.SqlAliasBase; -import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; import org.hibernate.sql.ast.spi.SqlAliasStemHelper; import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationState; @@ -6033,7 +6031,7 @@ public abstract class AbstractEntityPersister ); } - discriminatorMapping = generateDiscriminatorMapping(); + discriminatorMapping = generateDiscriminatorMapping( creationProcess ); } private void postProcessAttributeMappings(MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) { @@ -6146,7 +6144,7 @@ public abstract class AbstractEntityPersister return stateArrayPosition; } - protected EntityDiscriminatorMapping generateDiscriminatorMapping() { + protected EntityDiscriminatorMapping generateDiscriminatorMapping(MappingModelCreationProcess modelCreationProcess) { if ( getDiscriminatorType() == null) { return null; } @@ -6158,12 +6156,13 @@ public abstract class AbstractEntityPersister else { discriminatorColumnExpression = getDiscriminatorFormulaTemplate(); } - return new EntityDiscriminatorMappingImpl( + return new ExplicitColumnDiscriminatorMappingImpl ( this, + (DiscriminatorType) getTypeDiscriminatorMetadata().getResolutionType(), getTableName(), discriminatorColumnExpression, getDiscriminatorFormulaTemplate() != null, - (DiscriminatorType) getTypeDiscriminatorMetadata().getResolutionType() + modelCreationProcess ); } } @@ -6591,11 +6590,6 @@ public abstract class AbstractEntityPersister return discriminatorMapping; } - @Override - public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) { - return discriminatorMapping; - } - @Override public List getAttributeMappings() { if ( attributeMappings == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/DiscriminatorType.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/DiscriminatorType.java index 8289985804..baf18f6689 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/DiscriminatorType.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/DiscriminatorType.java @@ -22,6 +22,7 @@ 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.JdbcMapping; import org.hibernate.type.AbstractType; import org.hibernate.type.BasicType; import org.hibernate.type.descriptor.ValueBinder; @@ -50,6 +51,11 @@ public class DiscriminatorType extends AbstractType implements org.hibernate. return underlyingType; } + @Override + public JdbcMapping getJdbcMapping() { + return getUnderlyingType().getJdbcMapping(); + } + @Override public Class getReturnedClass() { return Class.class; diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java index 5c8c415fd0..7dc1d5276e 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java @@ -48,7 +48,7 @@ import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityVersionMapping; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl; -import org.hibernate.metamodel.mapping.internal.JoinedSubclassDiscriminatorMappingImpl; +import org.hibernate.metamodel.mapping.internal.CaseStatementDiscriminatorMappingImpl; import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper; import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess; import org.hibernate.persister.spi.PersisterCreationContext; @@ -130,7 +130,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { private final boolean[] isNullableSubclassTable; // subclass discrimination works by assigning particular - // values to certain combinations of null primary key + // values to certain combinations of not-null primary key // values in the outer join using an SQL CASE private final Map subclassesByDiscriminatorValue = new HashMap<>(); private final String[] discriminatorValues; @@ -580,7 +580,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { Subclass sc = siter.next(); subclassClosure[k] = sc.getEntityName(); final Table table = sc.getTable(); - subclassNameByTableName.put( table.getName(), sc.getClassName() ); + subclassNameByTableName.put( table.getName(), sc.getEntityName() ); try { if ( persistentClass.isPolymorphic() ) { final Object discriminatorValue; @@ -1218,17 +1218,6 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { return null; } - @Override - protected EntityDiscriminatorMapping generateDiscriminatorMapping() { - EntityMappingType superMappingType = getSuperMappingType(); - if ( superMappingType != null ) { - return superMappingType.getDiscriminatorMapping(); - } - else { - return super.generateDiscriminatorMapping(); - } - } - @Override protected EntityIdentifierMapping generateIdentifierMapping(MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) { final Type idType = getIdentifierType(); @@ -1268,6 +1257,40 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { ); } + @Override + protected EntityDiscriminatorMapping generateDiscriminatorMapping(MappingModelCreationProcess modelCreationProcess) { + EntityMappingType superMappingType = getSuperMappingType(); + if ( superMappingType != null ) { + return superMappingType.getDiscriminatorMapping(); + } + + if ( hasSubclasses() ) { + final String formula = getDiscriminatorFormulaTemplate(); + if ( explicitDiscriminatorColumnName != null || formula != null ) { + // even though this is a joined-hierarchy the user has defined an + // explicit discriminator column - so we can use the normal + // discriminator mapping + return super.generateDiscriminatorMapping( modelCreationProcess ); + } + + org.hibernate.persister.entity.DiscriminatorType discriminatorMetadataType = (org.hibernate.persister.entity.DiscriminatorType) getTypeDiscriminatorMetadata().getResolutionType(); + + // otherwise, we need to use the case-statement approach + return new CaseStatementDiscriminatorMappingImpl( + this, + subclassTableNameClosure, + notNullColumnTableNumbers, + notNullColumnNames, + discriminatorValues, + subclassNameByTableName, + discriminatorMetadataType, + modelCreationProcess + ); + } + + return null; + } + protected EntityIdentifierMapping generateNonEncapsulatedCompositeIdentifierMapping( MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor, @@ -1310,35 +1333,6 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { } } - @Override - public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) { - if ( hasSubclasses() ) { - if ( explicitDiscriminatorColumnName == null ) { - final String discriminatorColumnExpression; - if ( getDiscriminatorFormulaTemplate() == null ) { - discriminatorColumnExpression = getDiscriminatorColumnName(); - } - else { - discriminatorColumnExpression = getDiscriminatorFormulaTemplate(); - } - CaseSearchedExpressionInfo info = getCaseSearchedExpression( tableGroup ); - return new JoinedSubclassDiscriminatorMappingImpl( - this, - getTableName(), - discriminatorColumnExpression, - getDiscriminatorFormulaTemplate() != null, - info.caseSearchedExpression, - info.columnReferences, - (org.hibernate.persister.entity.DiscriminatorType) getTypeDiscriminatorMetadata().getResolutionType() - ); - } - else { - return super.getDiscriminatorMapping( tableGroup ); - } - } - return null; - } - @Override public void visitConstraintOrderedTables(ConstraintOrderedTableConsumer consumer) { for ( int i = 0; i < constraintOrderedTableNames.length; i++ ) { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java index 3daeeca8cc..9bff00e355 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java @@ -42,6 +42,7 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Table; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; +import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess; import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.query.NavigablePath; import org.hibernate.sql.SelectFragment; @@ -405,9 +406,9 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister { } @Override - protected EntityDiscriminatorMapping generateDiscriminatorMapping() { + protected EntityDiscriminatorMapping generateDiscriminatorMapping(MappingModelCreationProcess modelCreationProcess) { if ( hasSubclasses() ) { - return super.generateDiscriminatorMapping(); + return super.generateDiscriminatorMapping( modelCreationProcess ); } return null; } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/SemanticQueryWalker.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/SemanticQueryWalker.java index c21e0844af..be15644460 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/SemanticQueryWalker.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/SemanticQueryWalker.java @@ -9,6 +9,8 @@ package org.hibernate.query.sqm; import java.util.List; import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.metamodel.model.domain.internal.DiscriminatorSqmPath; +import org.hibernate.query.sqm.sql.internal.SelfInterpretingSqmPath; import org.hibernate.query.sqm.tree.cte.SqmCteContainer; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement; @@ -144,6 +146,8 @@ public interface SemanticQueryWalker { T visitEntityValuedPath(SqmEntityValuedSimplePath path); T visitPluralValuedPath(SqmPluralValuedSimplePath path); + + T visitSelfInterpretingSqmPath(SelfInterpretingSqmPath sqmPath); T visitIndexedPluralAccessPath(SqmIndexedCollectionAccessPath path); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmTreePrinter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmTreePrinter.java index 56008e9ae0..6addf07336 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmTreePrinter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmTreePrinter.java @@ -12,6 +12,7 @@ import java.util.Locale; import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.query.QueryLogging; import org.hibernate.query.sqm.SemanticQueryWalker; +import org.hibernate.query.sqm.sql.internal.SelfInterpretingSqmPath; import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.query.sqm.tree.cte.SqmCteContainer; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; @@ -584,6 +585,13 @@ public class SqmTreePrinter implements SemanticQueryWalker { return null; } + @Override + public Object visitSelfInterpretingSqmPath(SelfInterpretingSqmPath sqmPath) { + logWithIndentation( "-> [self-interpreting-path] - `%s`", sqmPath.getNavigablePath().getFullPath() ); + + return null; + } + @Override public Object visitEntityValuedPath(SqmEntityValuedSimplePath path) { logWithIndentation( "-> [entity-path] - `%s`", path.getNavigablePath().getFullPath() ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/spi/BaseSemanticQueryWalker.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/spi/BaseSemanticQueryWalker.java index a664a983f2..ecd7b6de96 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/spi/BaseSemanticQueryWalker.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/spi/BaseSemanticQueryWalker.java @@ -10,6 +10,7 @@ import java.util.List; import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.query.sqm.SemanticQueryWalker; +import org.hibernate.query.sqm.sql.internal.SelfInterpretingSqmPath; import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.query.sqm.tree.cte.SqmCteContainer; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; @@ -287,6 +288,11 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker extends Base return PluralValuedSimplePathInterpretation.from( sqmPath, this ); } + @Override + public Object visitSelfInterpretingSqmPath(SelfInterpretingSqmPath sqmPath) { + return sqmPath.interpret( this, this, jpaQueryComplianceEnabled ); + } + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // General expressions diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/DiscriminatorPathInterpretation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/DiscriminatorPathInterpretation.java new file mode 100644 index 0000000000..9ffb9d88a3 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/DiscriminatorPathInterpretation.java @@ -0,0 +1,70 @@ +/* + * 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.query.sqm.sql.internal; + +import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; +import org.hibernate.metamodel.mapping.EntityMappingType; +import org.hibernate.metamodel.mapping.JdbcMapping; +import org.hibernate.query.NavigablePath; +import org.hibernate.query.results.SqlSelectionImpl; +import org.hibernate.sql.ast.SqlAstWalker; +import org.hibernate.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlSelection; +import org.hibernate.sql.ast.tree.expression.Expression; +import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.results.graph.DomainResult; +import org.hibernate.sql.results.graph.DomainResultCreationState; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.spi.TypeConfiguration; + +/** + * SqmPathInterpretation and DomainResultProducer implementation for entity discriminator + * + * @author Steve Ebersole + */ +public class DiscriminatorPathInterpretation extends AbstractSqmPathInterpretation implements DomainResultProducer { + private final Expression expression; + + public DiscriminatorPathInterpretation( + NavigablePath navigablePath, + EntityMappingType mapping, + TableGroup tableGroup, + SqlAstCreationState sqlAstCreationState) { + super( navigablePath, mapping.getDiscriminatorMapping(), tableGroup ); + + final JdbcMapping jdbcMappingToUse = mapping.getDiscriminatorMapping().getJdbcMapping(); + expression = getDiscriminatorMapping().resolveSqlExpression( navigablePath, jdbcMappingToUse, tableGroup, sqlAstCreationState ); + } + + public EntityDiscriminatorMapping getDiscriminatorMapping() { + return (EntityDiscriminatorMapping) super.getExpressionType(); + } + + @Override + public EntityDiscriminatorMapping getExpressionType() { + return getDiscriminatorMapping(); + } + + @Override + public SqlSelection createSqlSelection( + int jdbcPosition, + int valuesArrayPosition, + JavaTypeDescriptor javaTypeDescriptor, + TypeConfiguration typeConfiguration) { + return new SqlSelectionImpl( valuesArrayPosition, getDiscriminatorMapping() ); + } + + @Override + public DomainResult> createDomainResult(String resultVariable, DomainResultCreationState creationState) { + return getDiscriminatorMapping().createDomainResult( getNavigablePath(), getTableGroup(), resultVariable, creationState ); + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + expression.accept( sqlTreeWalker ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SelfInterpretingSqmPath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SelfInterpretingSqmPath.java new file mode 100644 index 0000000000..972904e6c0 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SelfInterpretingSqmPath.java @@ -0,0 +1,26 @@ +/* + * 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.query.sqm.sql.internal; + +import org.hibernate.query.sqm.SemanticQueryWalker; +import org.hibernate.query.sqm.tree.domain.SqmPath; +import org.hibernate.sql.ast.spi.SqlAstCreationState; + +/** + * Optional contract for sqm-paths which need special interpretation handling + * + * @author Steve Ebersole + */ +public interface SelfInterpretingSqmPath extends SqmPath { + /** + * Perform the interpretation + */ + SqmPathInterpretation interpret( + SqlAstCreationState sqlAstCreationState, + SemanticQueryWalker sqmWalker, + boolean jpaQueryComplianceEnabled); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityResultGraphNode.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityResultGraphNode.java index e460a8130f..c633e6790b 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityResultGraphNode.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityResultGraphNode.java @@ -39,24 +39,12 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent private final BasicFetch discriminatorFetch; private final DomainResult rowIdResult; - private final EntityMappingType targetType; - public AbstractEntityResultGraphNode( EntityValuedModelPart referencedModelPart, NavigablePath navigablePath, DomainResultCreationState creationState) { - this( referencedModelPart, navigablePath, null, creationState ); - } - - @SuppressWarnings("WeakerAccess") - public AbstractEntityResultGraphNode( - EntityValuedModelPart referencedModelPart, - NavigablePath navigablePath, - EntityMappingType targetType, - DomainResultCreationState creationState) { super( referencedModelPart.getEntityMappingType(), navigablePath ); this.referencedModelPart = referencedModelPart; - this.targetType = targetType; final EntityMappingType entityDescriptor = referencedModelPart.getEntityMappingType(); @@ -100,9 +88,9 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent ); } - final EntityDiscriminatorMapping discriminatorMapping = getDiscriminatorMapping( entityDescriptor, entityTableGroup ); + final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping(); // No need to fetch the discriminator if this type does not have subclasses - if ( discriminatorMapping != null && entityDescriptor.getEntityPersister().getEntityMetamodel().hasSubclasses() ) { + if ( discriminatorMapping != null && entityDescriptor.hasSubclasses() ) { discriminatorFetch = discriminatorMapping.generateFetch( this, navigablePath.append( EntityDiscriminatorMapping.ROLE_NAME ), @@ -168,12 +156,6 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent } } - protected EntityDiscriminatorMapping getDiscriminatorMapping( - EntityMappingType entityDescriptor, - TableGroup entityTableGroup) { - return entityDescriptor.getDiscriminatorMapping( entityTableGroup ); - } - @Override public EntityMappingType getReferencedMappingContainer() { return getEntityValuedModelPart().getEntityMappingType(); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultJoinedSubclassImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultJoinedSubclassImpl.java index e1ee6818fb..bb7dca81c0 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultJoinedSubclassImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultJoinedSubclassImpl.java @@ -6,10 +6,7 @@ */ package org.hibernate.sql.results.graph.entity.internal; -import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; -import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityValuedModelPart; -import org.hibernate.persister.entity.JoinedSubclassEntityPersister; import org.hibernate.query.NavigablePath; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.results.graph.AssemblerCreationState; @@ -49,16 +46,4 @@ public class EntityResultJoinedSubclassImpl extends EntityResultImpl { return new EntityAssembler( getResultJavaTypeDescriptor(), initializer ); } - @Override - protected EntityDiscriminatorMapping getDiscriminatorMapping( - EntityMappingType entityDescriptor, - TableGroup entityTableGroup) { - final JoinedSubclassEntityPersister joinedSubclassEntityPersister = (JoinedSubclassEntityPersister) entityDescriptor; - if ( joinedSubclassEntityPersister.hasSubclasses() ) { - return joinedSubclassEntityPersister.getDiscriminatorMapping( entityTableGroup ); - } - else { - return null; - } - } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/ConvertedValueExtractor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/ConvertedValueExtractor.java index 209a296f0a..9cc7c3205b 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/ConvertedValueExtractor.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/ConvertedValueExtractor.java @@ -12,6 +12,7 @@ import java.sql.SQLException; import javax.persistence.AttributeConverter; import javax.persistence.PersistenceException; +import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.type.descriptor.ValueExtractor; import org.hibernate.type.descriptor.WrapperOptions; @@ -24,11 +25,11 @@ public class ConvertedValueExtractor implements ValueExtractor { private static final Logger log = Logger.getLogger( ConvertedValueExtractor.class ); private final ValueExtractor relationalExtractor; - private final AttributeConverter converter; + private final BasicValueConverter converter; public ConvertedValueExtractor( ValueExtractor relationalExtractor, - AttributeConverter converter) { + BasicValueConverter converter) { this.relationalExtractor = relationalExtractor; this.converter = converter; } @@ -50,7 +51,7 @@ public class ConvertedValueExtractor implements ValueExtractor { private O doConversion(R extractedValue) { try { - O convertedValue = converter.convertToEntityAttribute( extractedValue ); + O convertedValue = converter.toDomainValue( extractedValue ); log.debugf( "Converted value on extraction: %s -> %s", extractedValue, convertedValue ); return convertedValue; } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java b/hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java index 54330c5a2e..80924b5921 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java @@ -643,7 +643,12 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver { } @Override - public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) { + public Object getDiscriminatorValue() { + return null; + } + + @Override + public String getSubclassForDiscriminatorValue(Object value) { return null; } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java index 749eb12497..2732fb2b69 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java @@ -696,7 +696,12 @@ public class PersisterClassProviderTest { } @Override - public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) { + public Object getDiscriminatorValue() { + return null; + } + + @Override + public String getSubclassForDiscriminatorValue(Object value) { return null; } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java b/hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java index 185e014729..b04ea859d1 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java @@ -754,7 +754,12 @@ public class CustomPersister implements EntityPersister { } @Override - public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) { + public Object getDiscriminatorValue() { + return null; + } + + @Override + public String getSubclassForDiscriminatorValue(Object value) { return null; } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/Address.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/Address.java similarity index 86% rename from hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/Address.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/Address.java index 7a91856dc6..0134883a7c 100755 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/Address.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/Address.java @@ -6,7 +6,7 @@ */ //$Id: Address.java 4373 2004-08-18 09:18:34Z oneovthafew $ -package org.hibernate.orm.test.discriminator; +package org.hibernate.orm.test.mapping.inheritance.discriminator; /** diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/Customer.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/Customer.java similarity index 93% rename from hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/Customer.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/Customer.java index 6ee480e3e1..9361775d51 100755 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/Customer.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/Customer.java @@ -6,7 +6,7 @@ */ //$Id: Customer.java 4373 2004-08-18 09:18:34Z oneovthafew $ -package org.hibernate.orm.test.discriminator; +package org.hibernate.orm.test.mapping.inheritance.discriminator; /** diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/DiscriminatorQueryUsageTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/DiscriminatorQueryUsageTests.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/DiscriminatorQueryUsageTests.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/DiscriminatorQueryUsageTests.java index 3c8034c620..929313687e 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/DiscriminatorQueryUsageTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/DiscriminatorQueryUsageTests.java @@ -4,7 +4,7 @@ * 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.orm.test.discriminator; +package org.hibernate.orm.test.mapping.inheritance.discriminator; import javax.persistence.Tuple; @@ -21,7 +21,7 @@ import org.assertj.core.api.Assertions; * @author Steve Ebersole */ @DomainModel( - xmlMappings = "org/hibernate/orm/test/discriminator/Person.hbm.xml" + xmlMappings = "org/hibernate/orm/test/mapping/inheritance/discriminator/Person.hbm.xml" ) @SessionFactory public class DiscriminatorQueryUsageTests { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/DiscriminatorTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/DiscriminatorTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/DiscriminatorTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/DiscriminatorTest.java index 3cce0ecc31..87eb5ff4e3 100755 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/DiscriminatorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/DiscriminatorTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.orm.test.discriminator; +package org.hibernate.orm.test.mapping.inheritance.discriminator; import java.math.BigDecimal; import java.util.List; @@ -37,7 +37,7 @@ import static org.junit.jupiter.api.Assertions.fail; * @author Gavin King */ @DomainModel( - xmlMappings = "org/hibernate/orm/test/discriminator/Person.hbm.xml" + xmlMappings = "org/hibernate/orm/test/mapping/inheritance/discriminator/Person.hbm.xml" ) @SessionFactory public class DiscriminatorTest { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/Employee.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/Employee.java similarity index 94% rename from hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/Employee.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/Employee.java index abfac5a194..3bd7ac967d 100755 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/Employee.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/Employee.java @@ -6,7 +6,7 @@ */ //$Id: Employee.java 4373 2004-08-18 09:18:34Z oneovthafew $ -package org.hibernate.orm.test.discriminator; +package org.hibernate.orm.test.mapping.inheritance.discriminator; import java.math.BigDecimal; /** diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/PartTimeEmployee.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/PartTimeEmployee.java similarity index 90% rename from hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/PartTimeEmployee.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/PartTimeEmployee.java index 9167996dac..46146176f5 100755 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/PartTimeEmployee.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/PartTimeEmployee.java @@ -6,7 +6,7 @@ */ //$Id: Employee.java 4373 2004-08-18 09:18:34Z oneovthafew $ -package org.hibernate.orm.test.discriminator; +package org.hibernate.orm.test.mapping.inheritance.discriminator; import java.math.BigDecimal; /** diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/Person.hbm.xml b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/Person.hbm.xml similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/Person.hbm.xml rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/Person.hbm.xml index 9a6e354ae7..f1be23e9a9 100755 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/Person.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/Person.hbm.xml @@ -18,7 +18,7 @@ --> + "-//Hibernate/Hibernate Mapping DTD 4.0//EN" + "http://www.hibernate.org/dtd/hibernate-mapping-4.0.xsd"> - + @@ -24,7 +24,7 @@ - + diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/joined/JoinedSubclassInheritanceTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/joined/JoinedSubclassInheritanceTest.java similarity index 75% rename from hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/joined/JoinedSubclassInheritanceTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/joined/JoinedSubclassInheritanceTest.java index 7560d3e62f..ff6c2a4570 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/joined/JoinedSubclassInheritanceTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/joined/JoinedSubclassInheritanceTest.java @@ -1,10 +1,10 @@ /* * 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 . + * 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.orm.test.discriminator.joined; +package org.hibernate.orm.test.mapping.inheritance.discriminator.joined; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.orm.junit.DomainModel; @@ -21,7 +21,7 @@ import static org.hamcrest.MatcherAssert.assertThat; */ @TestForIssue(jiraKey = "HHH-11133") @DomainModel( - xmlMappings = "org/hibernate/orm/test/discriminator/joined/JoinedSubclassInheritance.hbm.xml" + xmlMappings = "org/hibernate/orm/test/mapping/inheritance/discriminator/joined/JoinedSubclassInheritance.hbm.xml" ) @SessionFactory public class JoinedSubclassInheritanceTest { @@ -37,9 +37,7 @@ public class JoinedSubclassInheritanceTest { @Test public void testConfiguredDiscriminatorValue(SessionFactoryScope scope) { final ChildEntity childEntity = new ChildEntity( 1, "Child" ); - scope.inTransaction( session -> - session.save( childEntity ) - ); + scope.inTransaction( session -> session.save( childEntity ) ); scope.inTransaction( session -> { ChildEntity ce = session.find( ChildEntity.class, 1 ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/joined/ParentEntity.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/joined/ParentEntity.java similarity index 89% rename from hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/joined/ParentEntity.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/joined/ParentEntity.java index ace042376f..df419c1aa8 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/discriminator/joined/ParentEntity.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/discriminator/joined/ParentEntity.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.orm.test.discriminator.joined; +package org.hibernate.orm.test.mapping.inheritance.discriminator.joined; /** * @author Chris Cranford diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/dynamic/DynamicJoinedInheritanceTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/dynamic/DynamicJoinedInheritanceTests.java new file mode 100644 index 0000000000..485b919aa6 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/dynamic/DynamicJoinedInheritanceTests.java @@ -0,0 +1,56 @@ +/* + * 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.orm.test.mapping.inheritance.dynamic; + +import java.util.HashMap; +import java.util.Map; + +import org.hibernate.tuple.DynamicMapInstantiator; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Steve Ebersole + */ +@DomainModel( xmlMappings = "org/hibernate/orm/test/mapping/inheritance/dynamic/JoinedMappings.hbm.xml" ) +@SessionFactory +public class DynamicJoinedInheritanceTests { + @Test + public void testLoading(SessionFactoryScope scope) { + scope.inTransaction( (session) -> { + final Map entity = (Map) session.get( "Sub", 1 ); + assertThat( entity ).isNotNull(); + assertThat( entity.get( DynamicMapInstantiator.KEY ) ).isNotNull(); + assertThat( entity.get( DynamicMapInstantiator.KEY ) ).isEqualTo( "Sub" ); + } ); + } + + @BeforeEach + public void createTestData(SessionFactoryScope scope) { + scope.inTransaction( (session) -> { + final HashMap entity = new HashMap<>(); + entity.put( "id", 1 ); + entity.put( "name", "sub" ); + entity.put( "subText", "" ); + session.save( "Sub", entity ); + } ); + } + + @AfterEach + public void dropTestData(SessionFactoryScope scope) { + scope.inTransaction( (session) -> { + session.createQuery( "delete Sub" ).executeUpdate(); + } ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/dynamic/JoinedMappings.hbm.xml b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/dynamic/JoinedMappings.hbm.xml new file mode 100644 index 0000000000..585f0fcb63 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/dynamic/JoinedMappings.hbm.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/dynamic/package-info.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/dynamic/package-info.java new file mode 100644 index 0000000000..920382e1bf --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/inheritance/dynamic/package-info.java @@ -0,0 +1,13 @@ +/* + * 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 for testing inheritance with dynamic entity models (MAP, entity-name) + * + * @author Steve Ebersole + */ +package org.hibernate.orm.test.mapping.inheritance.dynamic; \ No newline at end of file diff --git a/hibernate-core/src/test/resources/log4j2.properties b/hibernate-core/src/test/resources/log4j2.properties index 61d40382de..fc78962f4a 100644 --- a/hibernate-core/src/test/resources/log4j2.properties +++ b/hibernate-core/src/test/resources/log4j2.properties @@ -16,6 +16,11 @@ appender.unclosedSessionFactoryFile.fileName=target/tmp/log/UnclosedSessionFacto appender.unclosedSessionFactoryFile.layout.type=PatternLayout appender.unclosedSessionFactoryFile.layout.pattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n +appender.ddl.type=Console +appender.ddl.name=DDL +appender.ddl.layout.type=PatternLayout +appender.ddl.layout.pattern=%d{ABSOLUTE} %5p %c:%L - %m%n + rootLogger.level=info rootLogger.appenderRef.stdout.ref=STDOUT @@ -30,6 +35,7 @@ logger.tooling-schema-script-graph.name=org.hibernate.orm.tooling.schema.script. logger.hbm2ddl.name=org.hibernate.tool.hbm2ddl logger.hbm2ddl.level=trace + logger.testing-cache.name=org.hibernate.testing.cache logger.testing-cache.level=debug diff --git a/hibernate-envers/src/test/resources/log4j2.properties b/hibernate-envers/src/test/resources/log4j2.properties index affab5cfcd..ec4d623c41 100644 --- a/hibernate-envers/src/test/resources/log4j2.properties +++ b/hibernate-envers/src/test/resources/log4j2.properties @@ -9,6 +9,11 @@ appender.stdout.name=STDOUT appender.stdout.layout.type=PatternLayout appender.stdout.layout.pattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n +appender.ddl.type=Console +appender.ddl.name=DDL +appender.ddl.layout.type=PatternLayout +appender.ddl.layout.pattern=%d{ABSOLUTE} %5p %c:%L - %m%n + rootLogger.level=info rootLogger.appenderRef.stdout.ref=STDOUT @@ -18,13 +23,21 @@ logger.test.level=info # SQL Logging - HHH-6833 logger.sql.name=org.hibernate.SQL logger.sql.level=debug + logger.hbm2ddl.name=org.hibernate.tool.hbm2ddl -logger.hbm2ddl.level=debug +logger.hbm2ddl.level=trace +logger.hbm2ddl.appenderRef.stdout.ref=DDL logger.type-basic-binder.name=org.hibernate.type.descriptor.jdbc.BasicBinder logger.type-basic-binder.level=trace logger.type-basic-extractor.name=org.hibernate.type.descriptor.jdbc.BasicExtractor logger.type-basic-extractor.level=trace +logger.jdbc-bind.name=org.hibernate.orm.jdbc.bind +logger.jdbc-bind.level=trace + +logger.jdbc-extract.name=org.hibernate.orm.jdbc.extract +logger.jdbc-extract.level=trace + logger.additional-jaxb-mapping-producer-impl.name=org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl logger.additional-jaxb-mapping-producer-impl.level=trace \ No newline at end of file