diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle index f49bedde72..07b1295bc5 100644 --- a/hibernate-core/hibernate-core.gradle +++ b/hibernate-core/hibernate-core.gradle @@ -179,7 +179,9 @@ cleanEclipse { project.delete '.externalToolBuilders' project.delete 'hibernate-core-RunnableIdeTest.launch' } + tasks.eclipse.dependsOn(cleanEclipse) + eclipse { project { file { diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/NullnessHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/util/NullnessHelper.java index 471614b49e..8bad88850f 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/util/NullnessHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/util/NullnessHelper.java @@ -77,7 +77,7 @@ public class NullnessHelper { return value; } } - else { + else if ( value != null ) { return value; } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/DatabaseSnapshotExecutor.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/DatabaseSnapshotExecutor.java new file mode 100644 index 0000000000..b0c4b0b2de --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/DatabaseSnapshotExecutor.java @@ -0,0 +1,289 @@ +/* + * 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.loader.internal; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.hibernate.LockMode; +import org.hibernate.LockOptions; +import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.metamodel.mapping.EntityIdentifierMapping; +import org.hibernate.metamodel.mapping.EntityMappingType; +import org.hibernate.metamodel.mapping.JdbcMapping; +import org.hibernate.query.ComparisonOperator; +import org.hibernate.query.NavigablePath; +import org.hibernate.query.spi.QueryOptions; +import org.hibernate.query.spi.QueryParameterBindings; +import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.spi.SqlAliasBaseManager; +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.ast.tree.predicate.ComparisonPredicate; +import org.hibernate.sql.ast.tree.select.QuerySpec; +import org.hibernate.sql.ast.tree.select.SelectStatement; +import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; +import org.hibernate.sql.exec.internal.JdbcParameterImpl; +import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl; +import org.hibernate.sql.exec.spi.Callback; +import org.hibernate.sql.exec.spi.ExecutionContext; +import org.hibernate.sql.exec.spi.JdbcParameter; +import org.hibernate.sql.exec.spi.JdbcParameterBinding; +import org.hibernate.sql.exec.spi.JdbcParameterBindings; +import org.hibernate.sql.exec.spi.JdbcSelect; +import org.hibernate.sql.results.internal.RowTransformerPassThruImpl; +import org.hibernate.sql.results.internal.domain.basic.BasicResult; +import org.hibernate.sql.results.spi.DomainResult; + +import org.jboss.logging.Logger; + +/** + * @author Steve Ebersole + */ +class DatabaseSnapshotExecutor { + private static final Logger log = Logger.getLogger( DatabaseSnapshotExecutor.class ); + + private final EntityMappingType entityDescriptor; + private final SessionFactoryImplementor sessionFactory; + + private final JdbcSelect jdbcSelect; + private final List jdbcParameters; + + DatabaseSnapshotExecutor( + EntityMappingType entityDescriptor, + SessionFactoryImplementor sessionFactory) { + this.entityDescriptor = entityDescriptor; + this.sessionFactory = sessionFactory; + + final QuerySpec rootQuerySpec = new QuerySpec( true ); + + final SqlAliasBaseManager sqlAliasBaseManager = new SqlAliasBaseManager(); + + final LoaderSqlAstCreationState state = new LoaderSqlAstCreationState( + rootQuerySpec, + sqlAliasBaseManager, + LockOptions.READ, + sessionFactory + ); + + final NavigablePath rootPath = new NavigablePath( entityDescriptor.getEntityName() ); + + final TableGroup rootTableGroup = entityDescriptor.createRootTableGroup( + rootPath, + null, + null, + LockMode.NONE, + sqlAliasBaseManager, + state.getSqlExpressionResolver(), + () -> rootQuerySpec::applyPredicate, + sessionFactory + ); + + rootQuerySpec.getFromClause().addRoot( rootTableGroup ); + + jdbcParameters = new ArrayList<>( + entityDescriptor.getIdentifierMapping().getJdbcTypeCount( sessionFactory.getTypeConfiguration() ) + ); + final List domainResults = new ArrayList<>(); + + final NavigablePath idPath = rootPath.append( EntityIdentifierMapping.ROLE_LOCAL_NAME ); + entityDescriptor.getIdentifierMapping().visitColumns( + idPath, + rootTableGroup, + state, + (col, tab, jdbcMapping) -> { + final TableReference tableReference = rootTableGroup.resolveTableReference( tab ); + + final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcMapping ); + jdbcParameters.add( jdbcParameter ); + + final ColumnReference columnReference = (ColumnReference) state.getSqlExpressionResolver() + .resolveSqlExpression( + SqlExpressionResolver.createColumnReferenceKey( tableReference, col ), + s -> new ColumnReference( + tableReference, + col, + jdbcMapping, + sessionFactory + ) + ); + + rootQuerySpec.applyPredicate( + new ComparisonPredicate( + columnReference, + ComparisonOperator.EQUAL, + jdbcParameter + ) + ); + + final SqlSelection sqlSelection = state.getSqlExpressionResolver().resolveSqlSelection( + columnReference, + jdbcMapping.getJavaTypeDescriptor(), + sessionFactory.getTypeConfiguration() + ); + + rootQuerySpec.getSelectClause().addSqlSelection( sqlSelection ); + + //noinspection unchecked + domainResults.add( + new BasicResult( + sqlSelection.getValuesArrayPosition(), + null, + jdbcMapping.getJavaTypeDescriptor() + ) + ); + } + ); + + entityDescriptor.visitStateArrayContributors( + contributorMapping -> { + final NavigablePath attrPath = rootPath.append( contributorMapping.getAttributeName() ); + contributorMapping.visitColumns( + attrPath, + rootTableGroup, + state, + (columnExpression, containingTableExpression, jdbcMapping) -> { + final TableReference tableReference = rootTableGroup.resolveTableReference( + containingTableExpression ); + + final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcMapping ); + jdbcParameters.add( jdbcParameter ); + + final ColumnReference columnReference = (ColumnReference) state.getSqlExpressionResolver() + .resolveSqlExpression( + SqlExpressionResolver.createColumnReferenceKey( + tableReference, + columnExpression + ), + s -> new ColumnReference( + tableReference, + columnExpression, + jdbcMapping, + sessionFactory + ) + ); + + final SqlSelection sqlSelection = state.getSqlExpressionResolver() + .resolveSqlSelection( + columnReference, + jdbcMapping.getJavaTypeDescriptor(), + sessionFactory.getTypeConfiguration() + ); + + rootQuerySpec.getSelectClause().addSqlSelection( sqlSelection ); + + //noinspection unchecked + domainResults.add( + new BasicResult( + sqlSelection.getValuesArrayPosition(), + null, + jdbcMapping.getJavaTypeDescriptor() + ) + ); + } + ); + } + ); + + final Set tableNames = new HashSet<>(); + rootTableGroup.applyAffectedTableNames( tableNames::add ); + + final SelectStatement selectStatement = new SelectStatement( rootQuerySpec, domainResults, tableNames ); + + + final JdbcServices jdbcServices = sessionFactory.getJdbcServices(); + final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment(); + final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory(); + + jdbcSelect = sqlAstTranslatorFactory.buildSelectConverter( sessionFactory ).interpret( selectStatement ); + } + + Object[] loadDatabaseSnapshot(Object id, SharedSessionContractImplementor session) { + log.tracef( "Getting current persistent state for `%s#%s`", entityDescriptor.getEntityName(), id ); + + final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( + entityDescriptor.getIdentifierMapping().getJdbcTypeCount( sessionFactory.getTypeConfiguration() ) + ); + + final Iterator paramItr = jdbcParameters.iterator(); + + entityDescriptor.getIdentifierMapping().visitJdbcValues( + id, + Clause.WHERE, + (value, type) -> { + assert paramItr.hasNext(); + final JdbcParameter parameter = paramItr.next(); + jdbcParameterBindings.addBinding( + parameter, + new JdbcParameterBinding() { + @Override + public JdbcMapping getBindType() { + return type; + } + + @Override + public Object getBindValue() { + return value; + } + } + ); + }, + session + ); + assert !paramItr.hasNext(); + + final List list = JdbcSelectExecutorStandardImpl.INSTANCE.list( + jdbcSelect, + jdbcParameterBindings, + new ExecutionContext() { + @Override + public SharedSessionContractImplementor getSession() { + return session; + } + + @Override + public QueryOptions getQueryOptions() { + return QueryOptions.NONE; + } + + @Override + public QueryParameterBindings getQueryParameterBindings() { + return QueryParameterBindings.NO_PARAM_BINDINGS; + } + + @Override + public Callback getCallback() { + return null; + } + }, + RowTransformerPassThruImpl.instance() + ); + + if ( list.isEmpty() ) { + return null; + } + + final int size = list.size(); + final Object[] values = new Object[size]; + for ( int i = 0; i < size; i++ ) { + values[i] = list.get( i ); + } + + return values; + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/LoaderSqlAstCreationState.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/LoaderSqlAstCreationState.java new file mode 100644 index 0000000000..0cee77dc0d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/LoaderSqlAstCreationState.java @@ -0,0 +1,249 @@ +/* + * 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.loader.internal; + +import java.util.Collections; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; + +import javax.persistence.CacheRetrieveMode; +import javax.persistence.CacheStoreMode; + +import org.hibernate.CacheMode; +import org.hibernate.FlushMode; +import org.hibernate.LockMode; +import org.hibernate.LockOptions; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.graph.spi.AppliedGraph; +import org.hibernate.query.Limit; +import org.hibernate.query.NavigablePath; +import org.hibernate.query.ResultListTransformer; +import org.hibernate.query.TupleTransformer; +import org.hibernate.query.spi.QueryOptions; +import org.hibernate.query.sqm.sql.internal.SqlAstQuerySpecProcessingStateImpl; +import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.spi.FromClauseAccess; +import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; +import org.hibernate.sql.ast.spi.SqlAliasBaseManager; +import org.hibernate.sql.ast.spi.SqlAstCreationContext; +import org.hibernate.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlAstProcessingState; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.ast.tree.select.QuerySpec; +import org.hibernate.sql.results.spi.DomainResultCreationState; +import org.hibernate.sql.results.spi.Fetch; +import org.hibernate.sql.results.spi.FetchParent; + +/** + * Helper used when generating the database-snapshot select query + */ +public class LoaderSqlAstCreationState + implements SqlAstProcessingState, SqlAstCreationState, DomainResultCreationState, QueryOptions { + private final SqlAliasBaseManager sqlAliasBaseManager; + private final SqlAstCreationContext sf; + private final SqlAstQuerySpecProcessingStateImpl processingState; + private final FromClauseAccess fromClauseAccess; + private final LockOptions lockOptions; + private final BiFunction> fetchProcessor; + + public LoaderSqlAstCreationState( + QuerySpec querySpec, + SqlAliasBaseManager sqlAliasBaseManager, + FromClauseAccess fromClauseAccess, + LockOptions lockOptions, + BiFunction> fetchProcessor, + SqlAstCreationContext sf) { + this.sqlAliasBaseManager = sqlAliasBaseManager; + this.fromClauseAccess = fromClauseAccess; + this.lockOptions = lockOptions; + this.fetchProcessor = fetchProcessor; + this.sf = sf; + processingState = new SqlAstQuerySpecProcessingStateImpl( + querySpec, + this, + this, + () -> Clause.IRRELEVANT + ); + } + + + public LoaderSqlAstCreationState( + QuerySpec querySpec, + SqlAliasBaseManager sqlAliasBaseManager, + LockOptions lockOptions, + SessionFactoryImplementor sf) { + this( + querySpec, + sqlAliasBaseManager, + new FromClauseIndex(), + lockOptions, + (fetchParent,state) -> Collections.emptyList(), + sf + ); + } + + @Override + public SqlAstCreationContext getCreationContext() { + return sf; + } + + @Override + public SqlAstProcessingState getCurrentProcessingState() { + return this; + } + + @Override + public SqlExpressionResolver getSqlExpressionResolver() { + return processingState; + } + + @Override + public FromClauseAccess getFromClauseAccess() { + return fromClauseAccess; + } + + @Override + public SqlAliasBaseGenerator getSqlAliasBaseGenerator() { + return sqlAliasBaseManager; + } + + @Override + public LockMode determineLockMode(String identificationVariable) { + return lockOptions.getEffectiveLockMode( identificationVariable ); + } + + @Override + public List visitFetches(FetchParent fetchParent) { + return fetchProcessor.apply( fetchParent, this ); + } + + @Override + public SqlAstCreationState getSqlAstCreationState() { + return this; + } + + @Override + public SqlAstProcessingState getParentState() { + return null; + } + + private static class FromClauseIndex implements FromClauseAccess { + private TableGroup tableGroup; + + @Override + public TableGroup findTableGroup(NavigablePath navigablePath) { + if ( tableGroup != null ) { + if ( tableGroup.getNavigablePath().equals( navigablePath ) ) { + return tableGroup; + } + + throw new IllegalArgumentException( + "NavigablePath [" + navigablePath + "] did not match base TableGroup [" + + tableGroup.getNavigablePath() + "]" + ); + } + + return null; + } + + @Override + public void registerTableGroup(NavigablePath navigablePath, TableGroup tableGroup) { + assert tableGroup.getNavigablePath().equals( navigablePath ); + + if ( this.tableGroup != null ) { + if ( this.tableGroup != tableGroup ) { + throw new IllegalArgumentException( + "Base TableGroup [" + tableGroup.getNavigablePath() + "] already set - " + navigablePath + ); + } + assert this.tableGroup.getNavigablePath().equals( navigablePath ); + } + else { + this.tableGroup = tableGroup; + } + } + } + + @Override + public Integer getTimeout() { + return null; + } + + @Override + public FlushMode getFlushMode() { + return null; + } + + @Override + public Boolean isReadOnly() { + return null; + } + + @Override + public AppliedGraph getAppliedGraph() { + // todo (6.0) : use this from the "load settings" (Hibernate method args, map passed to JPA methods) + // the legacy approach is to temporarily set this on the Session's "load query influencers" + return null; + } + + @Override + public TupleTransformer getTupleTransformer() { + return null; + } + + @Override + public ResultListTransformer getResultListTransformer() { + return null; + } + + @Override + public Boolean isResultCachingEnabled() { + return false; + } + + @Override + public CacheRetrieveMode getCacheRetrieveMode() { + return CacheRetrieveMode.BYPASS; + } + + @Override + public CacheStoreMode getCacheStoreMode() { + return CacheStoreMode.BYPASS; + } + + @Override + public String getResultCacheRegionName() { + return null; + } + + @Override + public LockOptions getLockOptions() { + return lockOptions; + } + + @Override + public String getComment() { + return null; + } + + @Override + public List getDatabaseHints() { + return null; + } + + @Override + public Integer getFetchSize() { + return null; + } + + @Override + public Limit getLimit() { + return null; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/MetamodelSelectBuilderProcess.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/MetamodelSelectBuilderProcess.java new file mode 100644 index 0000000000..b4291db877 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/MetamodelSelectBuilderProcess.java @@ -0,0 +1,389 @@ +/* + * 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.loader.internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; + +import org.hibernate.LockMode; +import org.hibernate.LockOptions; +import org.hibernate.engine.FetchStyle; +import org.hibernate.engine.FetchTiming; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.spi.Loadable; +import org.hibernate.metamodel.mapping.BasicValuedModelPart; +import org.hibernate.metamodel.mapping.JdbcMapping; +import org.hibernate.metamodel.mapping.ModelPart; +import org.hibernate.query.ComparisonOperator; +import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.spi.SimpleFromClauseAccessImpl; +import org.hibernate.sql.ast.spi.SqlAliasBaseManager; +import org.hibernate.sql.ast.spi.SqlAstCreationContext; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.tree.expression.ColumnReference; +import org.hibernate.sql.ast.tree.expression.SqlTuple; +import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.ast.tree.from.TableReference; +import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate; +import org.hibernate.sql.ast.tree.predicate.InListPredicate; +import org.hibernate.sql.ast.tree.select.QuerySpec; +import org.hibernate.sql.ast.tree.select.SelectStatement; +import org.hibernate.sql.exec.internal.JdbcParameterImpl; +import org.hibernate.sql.exec.spi.JdbcParameter; +import org.hibernate.sql.results.spi.CircularFetchDetector; +import org.hibernate.sql.results.spi.DomainResult; +import org.hibernate.sql.results.spi.Fetch; +import org.hibernate.sql.results.spi.FetchParent; +import org.hibernate.sql.results.spi.Fetchable; +import org.hibernate.sql.results.spi.FetchableContainer; + +import org.jboss.logging.Logger; + +/** + * @author Steve Ebersole + */ +public class MetamodelSelectBuilderProcess { + private static final Logger log = Logger.getLogger( MetamodelSelectBuilderProcess.class ); + + interface SqlAstDescriptor { + SelectStatement getSqlAst(); + List getJdbcParameters(); + } + + @SuppressWarnings("WeakerAccess") + public static SqlAstDescriptor createSelect( + SessionFactoryImplementor sessionFactory, + Loadable loadable, + List partsToSelect, + ModelPart restrictedPart, + DomainResult domainResult, + int numberOfKeysToLoad, + LoadQueryInfluencers loadQueryInfluencers, + LockOptions lockOptions) { + final MetamodelSelectBuilderProcess process = new MetamodelSelectBuilderProcess( + sessionFactory, + loadable, + partsToSelect, + restrictedPart, + domainResult, + numberOfKeysToLoad, + loadQueryInfluencers, + lockOptions + ); + + return process.execute(); + } + + private final SqlAstCreationContext creationContext; + private final Loadable loadable; + private final List partsToSelect; + private final ModelPart restrictedPart; + private final DomainResult domainResult; + private final int numberOfKeysToLoad; + private final LoadQueryInfluencers loadQueryInfluencers; + private final LockOptions lockOptions; + + + private MetamodelSelectBuilderProcess( + SqlAstCreationContext creationContext, + Loadable loadable, + List partsToSelect, + ModelPart restrictedPart, + DomainResult domainResult, + int numberOfKeysToLoad, + LoadQueryInfluencers loadQueryInfluencers, + LockOptions lockOptions) { + this.creationContext = creationContext; + this.loadable = loadable; + this.partsToSelect = partsToSelect; + this.restrictedPart = restrictedPart; + this.domainResult = domainResult; + this.numberOfKeysToLoad = numberOfKeysToLoad; + this.loadQueryInfluencers = loadQueryInfluencers; + this.lockOptions = lockOptions != null ? lockOptions : LockOptions.NONE; + } + + private SqlAstDescriptor execute() { + final QuerySpec rootQuerySpec = new QuerySpec( true ); + final Set affectedTables = new HashSet<>(); + final List domainResults; + + final LoaderSqlAstCreationState sqlAstCreationState = new LoaderSqlAstCreationState( + rootQuerySpec, + new SqlAliasBaseManager(), + new SimpleFromClauseAccessImpl(), + lockOptions, + this::visitFetches, + creationContext + ); + + final NavigablePath rootNavigablePath = new NavigablePath( loadable.getPathName() ); + + final TableGroup rootTableGroup = loadable.createRootTableGroup( + rootNavigablePath, + null, + null, + lockOptions.getLockMode(), + sqlAstCreationState.getSqlAliasBaseManager(), + sqlAstCreationState.getSqlExpressionResolver(), + () -> rootQuerySpec::applyPredicate, + creationContext + ); + + rootQuerySpec.getFromClause().addRoot( rootTableGroup ); + sqlAstCreationState.getFromClauseAccess().registerTableGroup( rootNavigablePath, rootTableGroup ); + rootTableGroup.applyAffectedTableNames( affectedTables::add ); + + if ( partsToSelect != null && !partsToSelect.isEmpty() ) { + domainResults = new ArrayList<>(); + for ( ModelPart part : partsToSelect ) { + final NavigablePath navigablePath = rootNavigablePath.append( part.getPartName() ); + domainResults.add( + part.createDomainResult( + navigablePath, + rootTableGroup, + null, + sqlAstCreationState + ) + ); + } + } + else { + // use the one passed to the constructor or create one (maybe always create and pass?) + // allows re-use as they can be re-used to save on memory - they + // do not share state between + final DomainResult domainResult; + if ( this.domainResult != null ) { + // used the one passed to the constructor + domainResult = this.domainResult; + } + else { + // create one + domainResult = loadable.createDomainResult( + rootNavigablePath, + rootTableGroup, + null, + sqlAstCreationState + ); + } + + domainResults = Collections.singletonList( domainResult ); + } + + final int numberOfKeyColumns = restrictedPart.getJdbcTypeCount( + creationContext.getDomainModel().getTypeConfiguration() + ); + + final List jdbcParameters = new ArrayList<>( numberOfKeyColumns * numberOfKeysToLoad ); + + applyKeyRestriction( + rootQuerySpec, + rootNavigablePath, + rootTableGroup, + restrictedPart, + numberOfKeyColumns, + jdbcParameters::add, + sqlAstCreationState + ); + + return new SqlAstDescriptorImpl( + new SelectStatement( rootQuerySpec, domainResults, affectedTables ), + jdbcParameters + ); + } + + private void applyKeyRestriction( + QuerySpec rootQuerySpec, + NavigablePath rootNavigablePath, + TableGroup rootTableGroup, + ModelPart keyPart, + int numberOfKeyColumns, + Consumer jdbcParameterConsumer, + LoaderSqlAstCreationState sqlAstCreationState) { + final NavigablePath keyPath = rootNavigablePath.append( keyPart.getPartName() ); + + final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver(); + + if ( numberOfKeyColumns == 1 ) { + assert keyPart instanceof BasicValuedModelPart; + final BasicValuedModelPart basicKeyPart = (BasicValuedModelPart) keyPart; + + final JdbcMapping jdbcMapping = basicKeyPart.getJdbcMapping(); + + final String tableExpression = basicKeyPart.getContainingTableExpression(); + final String columnExpression = basicKeyPart.getMappedColumnExpression(); + final TableReference tableReference = rootTableGroup.resolveTableReference( tableExpression ); + final ColumnReference columnRef = (ColumnReference) sqlExpressionResolver.resolveSqlExpression( + SqlExpressionResolver.createColumnReferenceKey( tableReference, columnExpression ), + p -> new ColumnReference( + tableReference, + columnExpression, + jdbcMapping, + creationContext.getSessionFactory() + ) + ); + + if ( numberOfKeysToLoad == 1 ) { + final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcMapping ); + jdbcParameterConsumer.accept( jdbcParameter ); + + rootQuerySpec.applyPredicate( + new ComparisonPredicate( columnRef, ComparisonOperator.EQUAL, jdbcParameter ) + ); + } + else { + final InListPredicate predicate = new InListPredicate( columnRef ); + for ( int i = 0; i < numberOfKeysToLoad; i++ ) { + for ( int j = 0; j < numberOfKeyColumns; j++ ) { + final JdbcParameter jdbcParameter = new JdbcParameterImpl( columnRef.getJdbcMapping() ); + jdbcParameterConsumer.accept( jdbcParameter ); + predicate.addExpression( jdbcParameter ); + } + } + rootQuerySpec.applyPredicate( predicate ); + } + } + else { + final List columnReferences = new ArrayList<>( numberOfKeyColumns ); + + keyPart.visitColumns( + keyPath, + rootTableGroup, + sqlAstCreationState, + (columnExpression, containingTableExpression, jdbcMapping) -> { + final TableReference tableReference = rootTableGroup.resolveTableReference( containingTableExpression ); + columnReferences.add( + (ColumnReference) sqlExpressionResolver.resolveSqlExpression( + SqlExpressionResolver.createColumnReferenceKey( tableReference, columnExpression ), + p -> new ColumnReference( + tableReference, + columnExpression, + jdbcMapping, + creationContext.getSessionFactory() + ) + ) + ); + } + ); + + final SqlTuple tuple = new SqlTuple( columnReferences, keyPart ); + final InListPredicate predicate = new InListPredicate( tuple ); + + for ( int i = 0; i < numberOfKeysToLoad; i++ ) { + final List tupleParams = new ArrayList<>( ); + for ( int j = 0; j < numberOfKeyColumns; j++ ) { + final ColumnReference columnReference = columnReferences.get( j ); + final JdbcParameter jdbcParameter = new JdbcParameterImpl( columnReference.getJdbcMapping() ); + jdbcParameterConsumer.accept( jdbcParameter ); + } + final SqlTuple paramTuple = new SqlTuple( tupleParams, keyPart ); + predicate.addExpression( paramTuple ); + } + + rootQuerySpec.applyPredicate( predicate ); + } + } + + private final CircularFetchDetector circularFetchDetector = new CircularFetchDetector(); + private int fetchDepth = 0; + + private List visitFetches(FetchParent fetchParent, LoaderSqlAstCreationState creationState) { + log.tracef( "Starting visitation of FetchParent's Fetchables : %s", fetchParent.getNavigablePath() ); + + final List fetches = new ArrayList<>(); + + final Consumer processor = fetchable -> { + final NavigablePath fetchablePath = fetchParent.getNavigablePath().append( fetchable.getFetchableName() ); + + final Fetch biDirectionalFetch = circularFetchDetector.findBiDirectionalFetch( + fetchParent, + fetchable + ); + + if ( biDirectionalFetch != null ) { + fetches.add( biDirectionalFetch ); + return; + } + + LockMode lockMode = LockMode.READ; + FetchTiming fetchTiming = fetchable.getMappedFetchStrategy().getTiming(); + boolean joined = fetchable.getMappedFetchStrategy().getStyle() == FetchStyle.JOIN; + +// if ( loadable instanceof PluralValuedNavigable ) { +// // processing a collection-loader +// +// // if the `fetchable` is the "collection owner" and the collection owner is available in Session - don't join +// final String collectionMappedByProperty = ( (PluralValuedNavigable) rootContainer ).getCollectionDescriptor() +// .getMappedByProperty(); +// if ( collectionMappedByProperty != null && collectionMappedByProperty.equals( fetchable.getNavigableName() ) ) { +// joined = false; +// } +// } + + final Integer maximumFetchDepth = creationContext.getMaximumFetchDepth(); + + if ( maximumFetchDepth != null ) { + if ( fetchDepth == maximumFetchDepth ) { + joined = false; + } + else if ( fetchDepth > maximumFetchDepth ) { + return; + } + } + + try { + fetchDepth++; + Fetch fetch = fetchable.generateFetch( + fetchParent, + fetchablePath, + fetchTiming, + joined, + lockMode, + null, + creationState + ); + fetches.add( fetch ); + } + finally { + fetchDepth--; + } + }; + + final FetchableContainer referencedMappingContainer = fetchParent.getReferencedMappingContainer(); + referencedMappingContainer.visitKeyFetchables( processor, null ); + referencedMappingContainer.visitFetchables( processor, null ); + + return fetches; + } +} + +class SqlAstDescriptorImpl implements MetamodelSelectBuilderProcess.SqlAstDescriptor { + private final SelectStatement sqlAst; + private final List jdbcParameters; + + public SqlAstDescriptorImpl( + SelectStatement sqlAst, + List jdbcParameters) { + this.sqlAst = sqlAst; + this.jdbcParameters = jdbcParameters; + } + + @Override + public SelectStatement getSqlAst() { + return sqlAst; + } + + @Override + public List getJdbcParameters() { + return jdbcParameters; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderDynamicBatch.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderDynamicBatch.java new file mode 100644 index 0000000000..e188ae3b66 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderDynamicBatch.java @@ -0,0 +1,34 @@ +/* + * 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.loader.internal; + +import org.hibernate.LockOptions; +import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.loader.BatchFetchStyle; +import org.hibernate.metamodel.mapping.EntityMappingType; + +/** + * @author Steve Ebersole + */ +public class SingleIdEntityLoaderDynamicBatch extends SingleIdEntityLoaderSupport { + private final int batchSize; + + public SingleIdEntityLoaderDynamicBatch( + EntityMappingType entityDescriptor, + int batchSize, + SessionFactoryImplementor sessionFactory) { + super( entityDescriptor, sessionFactory ); + this.batchSize = batchSize; + } + + @Override + public T load(Object pkValue, LockOptions lockOptions, SharedSessionContractImplementor session) { + throw new NotYetImplementedFor6Exception( "Support for " + BatchFetchStyle.DYNAMIC + " not yet implemented" ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderLegacyBatch.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderLegacyBatch.java new file mode 100644 index 0000000000..4a00694fa2 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderLegacyBatch.java @@ -0,0 +1,34 @@ +/* + * 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.loader.internal; + +import org.hibernate.LockOptions; +import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.loader.BatchFetchStyle; +import org.hibernate.metamodel.mapping.EntityMappingType; + +/** + * @author Steve Ebersole + */ +public class SingleIdEntityLoaderLegacyBatch extends SingleIdEntityLoaderSupport { + private final int batchSize; + + public SingleIdEntityLoaderLegacyBatch( + EntityMappingType entityDescriptor, + int batchSize, + SessionFactoryImplementor sessionFactory) { + super( entityDescriptor, sessionFactory ); + this.batchSize = batchSize; + } + + @Override + public T load(Object pkValue, LockOptions lockOptions, SharedSessionContractImplementor session) { + throw new NotYetImplementedFor6Exception( "Support for " + BatchFetchStyle.LEGACY + " not yet implemented" ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderPaddedBatch.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderPaddedBatch.java new file mode 100644 index 0000000000..8926bd4954 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderPaddedBatch.java @@ -0,0 +1,39 @@ +/* + * 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.loader.internal; + +import org.hibernate.LockOptions; +import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.loader.BatchFetchStyle; +import org.hibernate.metamodel.mapping.EntityMappingType; + +/** + * @author Steve Ebersole + */ +public class SingleIdEntityLoaderPaddedBatch extends SingleIdEntityLoaderSupport implements Preparable { + private final int batchSize; + + public SingleIdEntityLoaderPaddedBatch( + EntityMappingType entityDescriptor, + int batchSize, + SessionFactoryImplementor sessionFactory) { + super( entityDescriptor, sessionFactory ); + this.batchSize = batchSize; + } + + @Override + public void prepare() { + + } + + @Override + public T load(Object pkValue, LockOptions lockOptions, SharedSessionContractImplementor session) { + throw new NotYetImplementedFor6Exception( "Support for " + BatchFetchStyle.PADDED + " not yet implemented" ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderProvidedQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderProvidedQueryImpl.java index 5cf34f1981..c25dd80a35 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderProvidedQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderProvidedQueryImpl.java @@ -7,10 +7,14 @@ package org.hibernate.loader.internal; import org.hibernate.LockOptions; -import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.spi.SingleIdEntityLoader; -import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.metamodel.mapping.EntityMappingType; +import org.hibernate.query.named.NamedQueryProducer; +import org.hibernate.query.named.NamedQueryRepository; +import org.hibernate.query.spi.QueryImplementor; +import org.hibernate.query.sql.spi.NamedNativeQueryMemento; /** * Implementation of SingleIdEntityLoader for cases where the application has @@ -19,22 +23,50 @@ import org.hibernate.persister.entity.EntityPersister; * @author Steve Ebersole */ public class SingleIdEntityLoaderProvidedQueryImpl implements SingleIdEntityLoader { - private final EntityPersister entityDescriptor; - private final String loadQueryName; + private final EntityMappingType entityDescriptor; + private final NamedQueryProducer namedQueryMemento; - public SingleIdEntityLoaderProvidedQueryImpl(EntityPersister entityDescriptor, String loadQueryName) { + public SingleIdEntityLoaderProvidedQueryImpl( + EntityMappingType entityDescriptor, + String loadQueryName, + SessionFactoryImplementor sessionFactory) { this.entityDescriptor = entityDescriptor; - this.loadQueryName = loadQueryName; + + this.namedQueryMemento = resolveNamedQuery( loadQueryName, sessionFactory ); + if ( namedQueryMemento == null ) { + throw new IllegalArgumentException( "Could not resolve named load-query [" + entityDescriptor.getEntityName() + "] : " + loadQueryName ); + } + } + + private static NamedQueryProducer resolveNamedQuery( + String queryName, + SessionFactoryImplementor sf) { + final NamedQueryRepository namedQueryRepository = sf.getQueryEngine().getNamedQueryRepository(); + + final NamedNativeQueryMemento nativeQueryMemento = namedQueryRepository.getNativeQueryMemento( queryName ); + if ( nativeQueryMemento != null ) { + return nativeQueryMemento; + } + + return namedQueryRepository.getHqlQueryMemento( queryName ); } @Override - public EntityPersister getLoadable() { + public EntityMappingType getLoadable() { return entityDescriptor; } @Override public T load(Object pkValue, LockOptions lockOptions, SharedSessionContractImplementor session) { - throw new NotYetImplementedFor6Exception( getClass() ); + //noinspection unchecked + final QueryImplementor query = namedQueryMemento.toQuery( + session, + entityDescriptor.getMappedJavaTypeDescriptor().getJavaType() + ); + + query.setParameter( 0, pkValue ); + + return query.uniqueResult(); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderStandardImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderStandardImpl.java index 9c2213c35a..ea6d0435a7 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderStandardImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderStandardImpl.java @@ -6,81 +6,56 @@ */ package org.hibernate.loader.internal; -import java.io.Serializable; import java.util.EnumMap; import org.hibernate.LockMode; import org.hibernate.LockOptions; -import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.loader.entity.BatchingEntityLoaderBuilder; import org.hibernate.loader.spi.InternalFetchProfile; -import org.hibernate.loader.spi.SingleIdEntityLoader; +import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.persister.entity.OuterJoinLoadable; -import org.hibernate.sql.exec.spi.JdbcSelect; /** * Standard implementation of SingleIdEntityLoader * * @author Steve Ebersole */ -public class SingleIdEntityLoaderStandardImpl implements SingleIdEntityLoader, Preparable { - private final EntityPersister entityDescriptor; +public class SingleIdEntityLoaderStandardImpl extends SingleIdEntityLoaderSupport implements Preparable { + private EnumMap selectByLockMode = new EnumMap<>( LockMode.class ); + private EnumMap selectByInternalCascadeProfile; - private EnumMap selectByLockMode = new EnumMap<>( LockMode.class ); - private EnumMap selectByInternalCascadeProfile; - - public SingleIdEntityLoaderStandardImpl(EntityPersister entityDescriptor) { - this.entityDescriptor = entityDescriptor; - } - - public void prepare() { - // see `org.hibernate.persister.entity.AbstractEntityPersister#createLoaders` + public SingleIdEntityLoaderStandardImpl( + EntityMappingType entityDescriptor, + SessionFactoryImplementor sessionFactory) { + super( entityDescriptor, sessionFactory ); } @Override - public EntityPersister getLoadable() { - return entityDescriptor; + public void prepare() { + // see `org.hibernate.persister.entity.AbstractEntityPersister#createLoaders` + } @Override public T load(Object key, LockOptions lockOptions, SharedSessionContractImplementor session) { - // todo (6.0) : TEMPORARY - use the legacy loaders + final SingleIdLoadPlan loadPlan = resolveLoadPlan( lockOptions, session ); - //noinspection unchecked - return (T) BatchingEntityLoaderBuilder.getBuilder( session.getFactory() ) - .buildLoader( (OuterJoinLoadable) entityDescriptor, -1, lockOptions.getLockMode(), session.getFactory(), session.getLoadQueryInfluencers() ) - .load( (Serializable) key, null, session, lockOptions ); - - - // todo (6.0) : see `org.hibernate.loader.internal.StandardSingleIdEntityLoader#load` in "upstream" 6.0 branch - // - and integrate as much as possible with the `o.h.loader.plan` stuff leveraging the similarities - // between the legacy LoadPlan stuff and DomainResult, Assembler, etc. -// -// final JdbcSelect jdbcSelect = resolveJdbcSelect( lockOptions, session ); -// -// throw new NotYetImplementedFor6Exception( getClass() ); + return loadPlan.load( key, lockOptions, session ); } - @Override - public Object[] loadDatabaseSnapshot(Object id, SharedSessionContractImplementor session) { - throw new NotYetImplementedFor6Exception( getClass() ); - } - - private JdbcSelect resolveJdbcSelect( + private SingleIdLoadPlan resolveLoadPlan( LockOptions lockOptions, SharedSessionContractImplementor session) { final LoadQueryInfluencers loadQueryInfluencers = session.getLoadQueryInfluencers(); - if ( entityDescriptor.isAffectedByEnabledFilters( loadQueryInfluencers ) ) { + if ( getLoadable().isAffectedByEnabledFilters( loadQueryInfluencers ) ) { // special case of not-cacheable based on enabled filters effecting this load. // // This case is special because the filters need to be applied in order to // properly restrict the SQL/JDBC results. For this reason it has higher // precedence than even "internal" fetch profiles. - return createJdbcSelect( lockOptions, loadQueryInfluencers, session.getFactory() ); + return createLoadPlan( lockOptions, loadQueryInfluencers, session.getFactory() ); } final InternalFetchProfile enabledInternalFetchProfile = loadQueryInfluencers.getEnabledInternalFetchProfile(); @@ -89,34 +64,56 @@ public class SingleIdEntityLoaderStandardImpl implements SingleIdEntityLoader if ( selectByInternalCascadeProfile == null ) { selectByInternalCascadeProfile = new EnumMap<>( InternalFetchProfile.class ); } - return selectByInternalCascadeProfile.computeIfAbsent( - loadQueryInfluencers.getEnabledInternalFetchProfile(), - internalFetchProfileType -> createJdbcSelect( lockOptions, loadQueryInfluencers, session.getFactory() ) + else { + final SingleIdLoadPlan existing = selectByInternalCascadeProfile.get( enabledInternalFetchProfile ); + if ( existing != null ) { + //noinspection unchecked + return existing; + } + } + + final SingleIdLoadPlan plan = createLoadPlan( + lockOptions, + loadQueryInfluencers, + session.getFactory() ); + selectByInternalCascadeProfile.put( enabledInternalFetchProfile, plan ); + + return plan; } } // otherwise see if the loader for the requested load can be cached - which // also means we should look in the cache for an existing one - final boolean cacheable = determineIfCacheable( lockOptions, loadQueryInfluencers ); + final boolean reusable = determineIfReusable( lockOptions, loadQueryInfluencers ); - if ( cacheable ) { - return selectByLockMode.computeIfAbsent( - lockOptions.getLockMode(), - lockMode -> createJdbcSelect( lockOptions, loadQueryInfluencers, session.getFactory() ) + if ( reusable ) { + final SingleIdLoadPlan existing = selectByLockMode.get( lockOptions.getLockMode() ); + if ( existing != null ) { + //noinspection unchecked + return existing; + } + + final SingleIdLoadPlan plan = createLoadPlan( + lockOptions, + loadQueryInfluencers, + session.getFactory() ); + selectByLockMode.put( lockOptions.getLockMode(), plan ); + + return plan; } - return createJdbcSelect( lockOptions, loadQueryInfluencers, session.getFactory() ); + return createLoadPlan( lockOptions, loadQueryInfluencers, session.getFactory() ); } - private boolean determineIfCacheable(LockOptions lockOptions, LoadQueryInfluencers loadQueryInfluencers) { - if ( entityDescriptor.isAffectedByEntityGraph( loadQueryInfluencers ) ) { + private boolean determineIfReusable(LockOptions lockOptions, LoadQueryInfluencers loadQueryInfluencers) { + if ( getLoadable().isAffectedByEntityGraph( loadQueryInfluencers ) ) { return false; } - if ( entityDescriptor.isAffectedByEnabledFetchProfiles( loadQueryInfluencers ) ) { + if ( getLoadable().isAffectedByEnabledFetchProfiles( loadQueryInfluencers ) ) { return false; } @@ -128,23 +125,24 @@ public class SingleIdEntityLoaderStandardImpl implements SingleIdEntityLoader return true; } - private JdbcSelect createJdbcSelect( + private SingleIdLoadPlan createLoadPlan( LockOptions lockOptions, LoadQueryInfluencers queryInfluencers, SessionFactoryImplementor sessionFactory) { - throw new NotYetImplementedFor6Exception( getClass() ); + final MetamodelSelectBuilderProcess.SqlAstDescriptor sqlAstDescriptor = MetamodelSelectBuilderProcess.createSelect( + sessionFactory, + getLoadable(), + null, + getLoadable().getIdentifierMapping(), + null, + 1, + queryInfluencers, + lockOptions + ); -// final MetamodelSelectBuilder selectBuilder = new SelectByEntityIdentifierBuilder( -// entityDescriptor.getFactory(), -// entityDescriptor -// ); -// final SqlAstSelectDescriptor selectDescriptor = selectBuilder -// .generateSelectStatement( 1, queryInfluencers, lockOptions ); -// -// -// return SqlAstSelectToJdbcSelectConverter.interpret( -// selectDescriptor, -// sessionFactory -// ); + return new SingleIdLoadPlan<>( + getLoadable().getIdentifierMapping(), + sqlAstDescriptor + ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderSupport.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderSupport.java new file mode 100644 index 0000000000..376363e9e7 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdEntityLoaderSupport.java @@ -0,0 +1,41 @@ +/* + * 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.loader.internal; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.loader.spi.SingleIdEntityLoader; +import org.hibernate.metamodel.mapping.EntityMappingType; + +/** + * @author Steve Ebersole + */ +public abstract class SingleIdEntityLoaderSupport implements SingleIdEntityLoader { + private final EntityMappingType entityDescriptor; + private final SessionFactoryImplementor sessionFactory; + + private DatabaseSnapshotExecutor databaseSnapshotExecutor; + + public SingleIdEntityLoaderSupport(EntityMappingType entityDescriptor, SessionFactoryImplementor sessionFactory) { + this.entityDescriptor = entityDescriptor; + this.sessionFactory = sessionFactory; + } + + @Override + public EntityMappingType getLoadable() { + return entityDescriptor; + } + + @Override + public Object[] loadDatabaseSnapshot(Object id, SharedSessionContractImplementor session) { + if ( databaseSnapshotExecutor == null ) { + databaseSnapshotExecutor = new DatabaseSnapshotExecutor( entityDescriptor, sessionFactory ); + } + + return databaseSnapshotExecutor.loadDatabaseSnapshot( id, session ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdLoadPlan.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdLoadPlan.java new file mode 100644 index 0000000000..cb0c0f2b6c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/SingleIdLoadPlan.java @@ -0,0 +1,120 @@ +/* + * 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.loader.internal; + +import java.util.Iterator; +import java.util.List; + +import org.hibernate.LockOptions; +import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.metamodel.mapping.JdbcMapping; +import org.hibernate.metamodel.mapping.ModelPart; +import org.hibernate.query.spi.QueryOptions; +import org.hibernate.query.spi.QueryParameterBindings; +import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; +import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl; +import org.hibernate.sql.exec.spi.Callback; +import org.hibernate.sql.exec.spi.ExecutionContext; +import org.hibernate.sql.exec.spi.JdbcParameter; +import org.hibernate.sql.exec.spi.JdbcParameterBinding; +import org.hibernate.sql.exec.spi.JdbcParameterBindings; +import org.hibernate.sql.exec.spi.JdbcSelect; +import org.hibernate.sql.results.internal.RowTransformerPassThruImpl; + +/** + * @author Steve Ebersole + */ +class SingleIdLoadPlan { + private final ModelPart restrictivePart; + private final MetamodelSelectBuilderProcess.SqlAstDescriptor sqlAstDescriptor; + + public SingleIdLoadPlan( + ModelPart restrictivePart, + MetamodelSelectBuilderProcess.SqlAstDescriptor sqlAstDescriptor) { + this.restrictivePart = restrictivePart; + this.sqlAstDescriptor = sqlAstDescriptor; + } + + T load(Object restrictedValue, LockOptions lockOptions, SharedSessionContractImplementor session) { + final SessionFactoryImplementor sessionFactory = session.getFactory(); + final JdbcServices jdbcServices = sessionFactory.getJdbcServices(); + final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment(); + final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory(); + + final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectConverter( sessionFactory ).interpret( sqlAstDescriptor.getSqlAst() ); + + final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( + restrictivePart.getJdbcTypeCount( sessionFactory.getTypeConfiguration() ) + ); + + final Iterator paramItr = sqlAstDescriptor.getJdbcParameters().iterator(); + + restrictivePart.visitJdbcValues( + restrictedValue, + Clause.WHERE, + (value, type) -> { + assert paramItr.hasNext(); + final JdbcParameter parameter = paramItr.next(); + jdbcParameterBindings.addBinding( + parameter, + new JdbcParameterBinding() { + @Override + public JdbcMapping getBindType() { + return type; + } + + @Override + public Object getBindValue() { + return value; + } + } + ); + }, + session + ); + assert !paramItr.hasNext(); + + final List list = JdbcSelectExecutorStandardImpl.INSTANCE.list( + jdbcSelect, + jdbcParameterBindings, + new ExecutionContext() { + @Override + public SharedSessionContractImplementor getSession() { + return session; + } + + @Override + public QueryOptions getQueryOptions() { + return QueryOptions.NONE; + } + + @Override + public QueryParameterBindings getQueryParameterBindings() { + return QueryParameterBindings.NO_PARAM_BINDINGS; + } + + @Override + public Callback getCallback() { + return null; + } + }, + RowTransformerPassThruImpl.instance() + ); + + if ( list.isEmpty() ) { + return null; + } + + //noinspection unchecked + return (T) list.get( 0 ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/Loadable.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/Loadable.java index 0b301b524d..1296333162 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/spi/Loadable.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/Loadable.java @@ -14,7 +14,7 @@ import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; import org.hibernate.sql.ast.spi.SqlAstCreationContext; @@ -36,6 +36,8 @@ public interface Loadable extends ModelPart, RootTableGroupProducer { boolean isAffectedByEntityGraph(LoadQueryInfluencers influencers); boolean isAffectedByEnabledFetchProfiles(LoadQueryInfluencers influencers); + String getPathName(); + @Override default TableGroup createRootTableGroup( NavigablePath navigablePath, diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/SingleEntityLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/SingleEntityLoader.java index fb3bfdc391..a74a40580b 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/spi/SingleEntityLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/SingleEntityLoader.java @@ -8,6 +8,7 @@ package org.hibernate.loader.spi; import org.hibernate.LockOptions; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.persister.entity.EntityPersister; /** @@ -17,7 +18,7 @@ import org.hibernate.persister.entity.EntityPersister; */ public interface SingleEntityLoader extends Loader { @Override - EntityPersister getLoadable(); + EntityMappingType getLoadable(); /** * Load an entity by a primary or unique key value. diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/AttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/AttributeMapping.java index 6338c24e54..29444b3d4a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/AttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/AttributeMapping.java @@ -16,6 +16,11 @@ import org.hibernate.property.access.spi.PropertyAccess; public interface AttributeMapping extends ModelPart, ValueMapping { String getAttributeName(); + @Override + default String getPartName() { + return getAttributeName(); + } + AttributeMetadataAccess getAttributeMetadataAccess(); ManagedMappingType getDeclaringType(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/CollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/CollectionPart.java index 3e29b639b7..7076f50e26 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/CollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/CollectionPart.java @@ -44,5 +44,10 @@ public interface CollectionPart extends ModelPart, Fetchable { Nature getNature(); - ModelPart getPartTypeDescriptor(); + MappingType getPartTypeDescriptor(); + + @Override + default String getPartName() { + return getNature().getName(); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java index c5c6e7e057..d2e7f0e540 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java @@ -175,6 +175,11 @@ public class EmbeddableMappingType implements ManagedMappingType { return representationStrategy; } + @Override + public String getPartName() { + return getEmbeddedValueMapping().getPartName(); + } + @Override public DomainResult createDomainResult( NavigablePath navigablePath, @@ -248,10 +253,8 @@ public class EmbeddableMappingType implements ManagedMappingType { Consumer action, Clause clause, TypeConfiguration typeConfiguration) { - visitAttributeMappings( - attributeMapping -> { - attributeMapping.visitJdbcTypes( action, clause, typeConfiguration ); - } + attributeMappings.forEach( + (s, attributeMapping) -> attributeMapping.visitJdbcTypes( action, clause, typeConfiguration ) ); } @@ -273,9 +276,11 @@ public class EmbeddableMappingType implements ManagedMappingType { public void visitJdbcValues( Object value, Clause clause, - JdbcValuesConsumer valuesConsumer, + JdbcValuesConsumer consumer, SharedSessionContractImplementor session) { - throw new NotYetImplementedFor6Exception( getClass() ); + attributeMappings.forEach( + (s, attributeMapping) -> attributeMapping.visitJdbcValues( value, clause, consumer, session ) + ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableValuedModelPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableValuedModelPart.java index c7c0898f85..e04e43b3af 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableValuedModelPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableValuedModelPart.java @@ -8,7 +8,7 @@ package org.hibernate.metamodel.mapping; import java.util.List; -import org.hibernate.query.sqm.sql.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.tree.expression.Expression; 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 7084a662aa..14387e86e4 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 @@ -11,4 +11,9 @@ package org.hibernate.metamodel.mapping; */ public interface EntityDiscriminatorMapping extends VirtualModelPart, BasicValuedModelPart { String ROLE_NAME = "{discriminator}"; + + @Override + default String getPartName() { + return ROLE_NAME; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityIdentifierMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityIdentifierMapping.java index 9dc43969da..43cb6cea99 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityIdentifierMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityIdentifierMapping.java @@ -15,4 +15,9 @@ public interface EntityIdentifierMapping extends ValueMapping, ModelPart { String ROLE_LOCAL_NAME = "{id}"; PropertyAccess getPropertyAccess(); + + @Override + default String getPartName() { + return ROLE_LOCAL_NAME; + } } 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 ddb1758da6..19849169c0 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 @@ -9,12 +9,25 @@ package org.hibernate.metamodel.mapping; import java.util.Collection; import java.util.Map; import java.util.function.Consumer; +import java.util.function.Supplier; +import org.hibernate.LockMode; import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.loader.spi.Loadable; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.JoinType; +import org.hibernate.sql.ast.spi.SqlAliasBase; +import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; +import org.hibernate.sql.ast.spi.SqlAstCreationContext; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.ast.tree.from.TableReferenceCollector; +import org.hibernate.sql.ast.tree.predicate.Predicate; import org.hibernate.sql.results.spi.DomainResultAssembler; -import org.hibernate.sql.results.spi.Fetchable; import org.hibernate.sql.results.spi.RowProcessingState; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import static org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer.UNFETCHED_PROPERTY; @@ -25,7 +38,7 @@ import static org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer.UNFETCH * * @author Steve Ebersole */ -public interface EntityMappingType extends ManagedMappingType { +public interface EntityMappingType extends ManagedMappingType, Loadable { /** * Safety-net. * @@ -33,15 +46,30 @@ public interface EntityMappingType extends ManagedMappingType { */ EntityPersister getEntityPersister(); - default String getEntityName() { - return getEntityPersister().getEntityName(); + String getEntityName(); + + @Override + default String getPartName() { + return getEntityName(); + } + + @Override + default String getPathName() { + return getEntityName(); + } + + @Override + default JavaTypeDescriptor getJavaTypeDescriptor() { + return getMappedJavaTypeDescriptor(); } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Inheritance default AttributeMapping findDeclaredAttributeMapping(String name) { - return null; + throw new NotYetImplementedFor6Exception( getClass() ); + // or ? + //throw new UnsupportedOperationException(); } /** @@ -89,7 +117,7 @@ public interface EntityMappingType extends ManagedMappingType { EntityVersionMapping getVersionMapping(); default EntityDiscriminatorMapping getDiscriminatorMapping() { - return null; + throw new NotYetImplementedFor6Exception( getClass() ); } NaturalIdMapping getNaturalIdMapping(); @@ -157,4 +185,80 @@ public interface EntityMappingType extends ManagedMappingType { attributeMapping -> mappingConsumer.accept( (StateArrayContributorMapping) attributeMapping ) ); } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Loadable + + @Override + default boolean isAffectedByEnabledFilters(LoadQueryInfluencers influencers) { + return getEntityPersister().isAffectedByEnabledFilters( influencers ); + } + + @Override + default boolean isAffectedByEntityGraph(LoadQueryInfluencers influencers) { + return getEntityPersister().isAffectedByEntityGraph( influencers ); + } + + @Override + default boolean isAffectedByEnabledFetchProfiles(LoadQueryInfluencers influencers) { + return getEntityPersister().isAffectedByEnabledFetchProfiles( influencers ); + } + + @Override + default TableGroup createRootTableGroup( + NavigablePath navigablePath, + String explicitSourceAlias, + JoinType tableReferenceJoinType, + LockMode lockMode, + SqlAliasBaseGenerator aliasBaseGenerator, + SqlExpressionResolver sqlExpressionResolver, + Supplier> additionalPredicateCollectorAccess, + SqlAstCreationContext creationContext) { + return getEntityPersister().createRootTableGroup( + navigablePath, + explicitSourceAlias, + tableReferenceJoinType, + lockMode, + aliasBaseGenerator, + sqlExpressionResolver, + additionalPredicateCollectorAccess, + creationContext + ); + } + + @Override + default void applyTableReferences( + SqlAliasBase sqlAliasBase, + JoinType baseJoinType, + TableReferenceCollector collector, + SqlExpressionResolver sqlExpressionResolver, + SqlAstCreationContext creationContext) { + getEntityPersister().applyTableReferences( sqlAliasBase, baseJoinType, collector, sqlExpressionResolver, creationContext ); + } + + @Override + default int getNumberOfAttributeMappings() { + return getEntityPersister().getNumberOfAttributeMappings(); + } + + @Override + default Collection getAttributeMappings() { + return getEntityPersister().getAttributeMappings(); + } + + @Override + default JavaTypeDescriptor getMappedJavaTypeDescriptor() { + return getEntityPersister().getMappedJavaTypeDescriptor(); + } + + @Override + default String getSqlAliasStem() { + return getEntityPersister().getSqlAliasStem(); + } + + @Override + default int getNumberOfFetchables() { + return getEntityPersister().getNumberOfFetchables(); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityValuedModelPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityValuedModelPart.java index 2ba5f1bc35..803748809e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityValuedModelPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityValuedModelPart.java @@ -87,8 +87,8 @@ public interface EntityValuedModelPart extends FetchableContainer { default void visitJdbcValues( Object value, Clause clause, - JdbcValuesConsumer valuesConsumer, + JdbcValuesConsumer consumer, SharedSessionContractImplementor session) { - getEntityMappingType().visitJdbcValues( value, clause, valuesConsumer, session ); + getEntityMappingType().visitJdbcValues( value, clause, consumer, session ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ManagedMappingType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ManagedMappingType.java index c8c875c562..4036fde2a1 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ManagedMappingType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ManagedMappingType.java @@ -11,6 +11,7 @@ import java.util.function.Consumer; import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.sql.results.spi.FetchableContainer; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; /** * Commonality in regards to the mapping type system for all managed domain @@ -19,6 +20,10 @@ import org.hibernate.sql.results.spi.FetchableContainer; * @author Steve Ebersole */ public interface ManagedMappingType extends MappingType, FetchableContainer { + @Override + default JavaTypeDescriptor getJavaTypeDescriptor() { + return getMappedJavaTypeDescriptor(); + } /** * Get the number of attributes defined on this class and any supers diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/MappingType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/MappingType.java index 15276a2893..141d1679e2 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/MappingType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/MappingType.java @@ -13,11 +13,6 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor; * * @author Steve Ebersole */ -public interface MappingType extends ModelPart { +public interface MappingType { JavaTypeDescriptor getMappedJavaTypeDescriptor(); - - @Override - default JavaTypeDescriptor getJavaTypeDescriptor() { - return getMappedJavaTypeDescriptor(); - } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ModelPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ModelPart.java index a934501691..0bee03eb54 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ModelPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ModelPart.java @@ -6,16 +6,24 @@ */ package org.hibernate.metamodel.mapping; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate; +import org.hibernate.sql.ast.tree.predicate.Predicate; import org.hibernate.sql.results.spi.DomainResult; import org.hibernate.sql.results.spi.DomainResultCreationState; import org.hibernate.query.sqm.sql.internal.DomainResultProducer; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; /** - * Describes a mapping of related to any part of the app's domain model - e.g. + * Describes a mapping related to any part of the app's domain model - e.g. * an attribute, an entity identifier, collection elements, etc * * @see DomainResultProducer @@ -28,6 +36,8 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor; public interface ModelPart extends MappingModelExpressable { JavaTypeDescriptor getJavaTypeDescriptor(); + String getPartName(); + /** * Create a DomainResult for a specific reference to this ModelPart. */ @@ -48,4 +58,32 @@ public interface ModelPart extends MappingModelExpressable { DomainResultCreationState creationState) { throw new NotYetImplementedFor6Exception( getClass() ); } + + /** + * Apply SQL selections for a specific reference to this ModelPart outside the domain query's root select clause. + */ + default void applySqlSelections( + NavigablePath navigablePath, + TableGroup tableGroup, + DomainResultCreationState creationState, + BiConsumer selectionConsumer) { + throw new NotYetImplementedFor6Exception( getClass() ); + } + + default void visitColumns( + NavigablePath navigablePath, + TableGroup tableGroup, + DomainResultCreationState creationState, + ColumnConsumer consumer) { + + } + + @FunctionalInterface + interface ColumnConsumer { + // todo (6.0) : pass values `updateable`, `checkable`, etc + void accept( + String columnExpression, + String containingTableExpression, + JdbcMapping jdbcMapping); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedCollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedCollectionPart.java index 4473f339e4..44c9e95fda 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedCollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedCollectionPart.java @@ -19,7 +19,7 @@ import org.hibernate.metamodel.mapping.MappingType; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +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; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedSingularAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedSingularAttributeMapping.java index a72950ce2d..d4f509facd 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedSingularAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedSingularAttributeMapping.java @@ -20,8 +20,8 @@ import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlAstCreationState; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.expression.ColumnReference; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CollectionIdentifierDescriptorImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CollectionIdentifierDescriptorImpl.java index 64bf6898f0..24bf03314e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CollectionIdentifierDescriptorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CollectionIdentifierDescriptorImpl.java @@ -10,8 +10,8 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlAstCreationState; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.expression.ColumnReference; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java index a0df6b9dcc..b9f9ff771f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java @@ -26,14 +26,14 @@ import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess; import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlAstCreationState; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; import org.hibernate.sql.ast.spi.SqlAstCreationContext; +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.expression.SqlTuple; @@ -128,6 +128,15 @@ public class EmbeddedAttributeMapping getEmbeddableTypeDescriptor().visitJdbcValues( value, clause, valuesConsumer, session ); } + @Override + public void visitColumns( + NavigablePath navigablePath, + TableGroup tableGroup, + DomainResultCreationState creationState, + ColumnConsumer consumer) { + getEmbeddableTypeDescriptor().visitColumns( navigablePath, tableGroup, creationState, consumer ); + } + @Override public DomainResult createDomainResult( NavigablePath navigablePath, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedCollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedCollectionPart.java index 5536337942..8078cdf883 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedCollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedCollectionPart.java @@ -21,8 +21,8 @@ import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlAstCreationState; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.JoinType; 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 index 7ff65fee8c..ced05cc2e0 100644 --- 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 @@ -15,8 +15,8 @@ import org.hibernate.metamodel.mapping.MappingType; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlAstCreationState; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +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.expression.ColumnReference; import org.hibernate.sql.ast.tree.from.TableGroup; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java index 313bd7acb5..b82b2fa3eb 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java @@ -68,9 +68,9 @@ import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.persister.walking.internal.FetchStrategyHelper; import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.spi.SqlAliasStemHelper; +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.expression.Expression; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java index 84d1989924..0a96142156 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java @@ -24,8 +24,8 @@ import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlAstCreationState; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java index 82491b3f2a..6aaca46221 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java @@ -9,8 +9,8 @@ package org.hibernate.metamodel.mapping.internal; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlAstCreationState; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +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.expression.ColumnReference; import org.hibernate.sql.ast.tree.from.TableGroup; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DomainModelHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DomainModelHelper.java index f536685dac..4c34ad7e32 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DomainModelHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DomainModelHelper.java @@ -6,33 +6,10 @@ */ package org.hibernate.metamodel.model.domain.internal; -import javax.persistence.metamodel.Bindable; - -import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.metamodel.mapping.MappingModelExpressable; -import org.hibernate.metamodel.mapping.ModelPart; -import org.hibernate.metamodel.mapping.Queryable; -import org.hibernate.metamodel.model.domain.AnyMappingDomainType; -import org.hibernate.metamodel.model.domain.BasicDomainType; -import org.hibernate.metamodel.model.domain.DomainType; import org.hibernate.metamodel.model.domain.EmbeddableDomainType; -import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.JpaMetamodel; import org.hibernate.metamodel.model.domain.ManagedDomainType; -import org.hibernate.metamodel.spi.DomainMetamodel; -import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.SqmExpressable; -import org.hibernate.query.sqm.SqmPathSource; -import org.hibernate.query.sqm.SqmTreeTransformationLogger; -import org.hibernate.query.sqm.sql.SqlAstCreationState; -import org.hibernate.query.sqm.tree.SqmTypedNode; -import org.hibernate.query.sqm.tree.domain.SqmPath; -import org.hibernate.query.sqm.tree.domain.SqmTreatedPath; -import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.type.BasicType; /** * Helper containing utilities useful for domain model handling diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index 04fcec82bf..64701dea44 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -85,7 +85,7 @@ import org.hibernate.persister.walking.spi.CompositeCollectionElementDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.pretty.MessageHelper; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.Alias; import org.hibernate.sql.SelectFragment; import org.hibernate.sql.SimpleSelect; diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java index 92fd8240aa..dffc8b89bf 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java @@ -28,7 +28,7 @@ import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.domain.NavigableRole; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.CollectionDefinition; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAstCreationContext; 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 ef924c70ab..0c2d1933b2 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,14 +107,18 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.jdbc.Expectation; import org.hibernate.jdbc.Expectations; import org.hibernate.jdbc.TooManyRowsAffectedException; +import org.hibernate.loader.BatchFetchStyle; import org.hibernate.loader.custom.sql.SQLQueryParser; import org.hibernate.loader.entity.BatchingEntityLoaderBuilder; import org.hibernate.loader.entity.CascadeEntityLoader; import org.hibernate.loader.entity.EntityLoader; import org.hibernate.loader.entity.UniqueEntityLoader; +import org.hibernate.loader.internal.SingleIdEntityLoaderDynamicBatch; import org.hibernate.loader.internal.MultiIdEntityLoaderStandardImpl; import org.hibernate.loader.internal.NaturalIdLoaderStandardImpl; import org.hibernate.loader.internal.Preparable; +import org.hibernate.loader.internal.SingleIdEntityLoaderLegacyBatch; +import org.hibernate.loader.internal.SingleIdEntityLoaderPaddedBatch; import org.hibernate.loader.internal.SingleIdEntityLoaderProvidedQueryImpl; import org.hibernate.loader.internal.SingleIdEntityLoaderStandardImpl; import org.hibernate.loader.spi.Loader; @@ -162,7 +166,7 @@ import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.property.access.spi.Setter; import org.hibernate.query.ComparisonOperator; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.Alias; import org.hibernate.sql.Delete; import org.hibernate.sql.Insert; @@ -229,6 +233,10 @@ public abstract class AbstractEntityPersister private final String sqlAliasStem; + private final SingleIdEntityLoader singleIdEntityLoader; + private final MultiIdEntityLoader multiIdEntityLoader; + private final NaturalIdLoader naturalIdLoader; + @@ -318,9 +326,6 @@ public abstract class AbstractEntityPersister private final Set affectingFetchProfileNames = new HashSet<>(); - private final SingleIdEntityLoader singleIdEntityLoader; - private final MultiIdEntityLoader multiIdEntityLoader; - private final NaturalIdLoader naturalIdLoader; private final Map uniqueKeyLoaders = new HashMap(); private final Map lockers = new HashMap(); @@ -681,11 +686,17 @@ public abstract class AbstractEntityPersister rowIdName = bootDescriptor.getRootTable().getRowId(); if ( bootDescriptor.getLoaderName() != null ) { - singleIdEntityLoader = new SingleIdEntityLoaderProvidedQueryImpl( this, bootDescriptor.getLoaderName() ); + singleIdEntityLoader = new SingleIdEntityLoaderProvidedQueryImpl( + this, + bootDescriptor.getLoaderName(), + factory + ); + } + else if ( batchSize > 1 ) { + singleIdEntityLoader = createBatchingIdEntityLoader( this, batchSize, factory ); } - // todo (6.0) : account for batch-size and batch-load strategies else { - singleIdEntityLoader = new SingleIdEntityLoaderStandardImpl( this ); + singleIdEntityLoader = new SingleIdEntityLoaderStandardImpl( this, factory ); } multiIdEntityLoader = new MultiIdEntityLoaderStandardImpl( this ); @@ -991,6 +1002,28 @@ public abstract class AbstractEntityPersister } + private static SingleIdEntityLoader createBatchingIdEntityLoader( + EntityMappingType entityDescriptor, + int batchSize, + SessionFactoryImplementor factory) { + final BatchFetchStyle batchFetchStyle = factory.getSettings().getBatchFetchStyle(); + + switch ( batchFetchStyle ) { + case LEGACY: { + return new SingleIdEntityLoaderLegacyBatch( entityDescriptor, batchSize, factory ); + } + case DYNAMIC: { + return new SingleIdEntityLoaderDynamicBatch( entityDescriptor, batchSize, factory ); + } + case PADDED: { + return new SingleIdEntityLoaderPaddedBatch( entityDescriptor, batchSize, factory ); + } + default: { + throw new UnsupportedOperationException( "BatchFetchStyle [" + batchFetchStyle.name() + "] not supported" ); + } + } + } + @SuppressWarnings("RedundantIfStatement") private boolean determineWhetherToInvalidateCache( PersistentClass persistentClass, @@ -1146,6 +1179,11 @@ public abstract class AbstractEntityPersister return sqlAliasStem; } + @Override + public String getPartName() { + return getEntityName(); + } + @Override public DomainResult createDomainResult( NavigablePath navigablePath, @@ -1777,66 +1815,8 @@ public abstract class AbstractEntityPersister return select; } - public Object[] getDatabaseSnapshot(Serializable id, SharedSessionContractImplementor session) - throws HibernateException { - - if ( LOG.isTraceEnabled() ) { - LOG.tracev( - "Getting current persistent state for: {0}", MessageHelper.infoString( - this, - id, - getFactory() - ) - ); - } - - try { - PreparedStatement ps = session - .getJdbcCoordinator() - .getStatementPreparer() - .prepareStatement( getSQLSnapshotSelectString() ); - try { - getIdentifierType().nullSafeSet( ps, id, 1, session ); - //if ( isVersioned() ) getVersionType().nullSafeSet( ps, version, getIdentifierColumnSpan()+1, session ); - ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( ps ); - try { - //if there is no resulting row, return null - if ( !rs.next() ) { - return null; - } - //otherwise return the "hydrated" state (ie. associations are not resolved) - Type[] types = getPropertyTypes(); - Object[] values = new Object[types.length]; - boolean[] includeProperty = getPropertyUpdateability(); - for ( int i = 0; i < types.length; i++ ) { - if ( includeProperty[i] ) { - values[i] = types[i].hydrate( - rs, - getPropertyAliases( "", i ), - session, - null - ); //null owner ok?? - } - } - return values; - } - finally { - session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( rs, ps ); - } - } - finally { - session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( ps ); - session.getJdbcCoordinator().afterStatementExecution(); - } - } - catch (SQLException e) { - throw session.getJdbcServices().getSqlExceptionHelper().convert( - e, - "could not retrieve snapshot: " + MessageHelper.infoString( this, id, getFactory() ), - getSQLSnapshotSelectString() - ); - } - + public Object[] getDatabaseSnapshot(Serializable id, SharedSessionContractImplementor session) throws HibernateException { + return singleIdEntityLoader.loadDatabaseSnapshot( id, session ); } @Override @@ -5247,6 +5227,10 @@ public abstract class AbstractEntityPersister if ( entity instanceof SelfDirtinessTracker ) { ( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes(); } + + if ( singleIdEntityLoader instanceof Preparable ) { + ( (Preparable) singleIdEntityLoader ).prepare(); + } } public String[] getPropertyNames() { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java index 35a29ba131..0ba47a353e 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java @@ -38,13 +38,8 @@ import org.hibernate.metamodel.model.domain.NavigableRole; import org.hibernate.metamodel.spi.EntityRepresentationStrategy; import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; -import org.hibernate.sql.ast.JoinType; -import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasStemHelper; -import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.tree.from.RootTableGroupProducer; -import org.hibernate.sql.ast.tree.from.TableReferenceCollector; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.type.Type; 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 492469fa52..d83258e5e4 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 @@ -6,6 +6,15 @@ */ package org.hibernate.persister.entity; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.MappingException; @@ -34,7 +43,6 @@ import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Table; import org.hibernate.mapping.Value; import org.hibernate.persister.spi.PersisterCreationContext; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; import org.hibernate.sql.CaseFragment; import org.hibernate.sql.InFragment; import org.hibernate.sql.Insert; @@ -46,15 +54,6 @@ import org.hibernate.type.Type; import org.jboss.logging.Logger; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - /** * An EntityPersister implementing the normalized "table-per-subclass" * mapping strategy diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java index db0816302e..3631a9e79c 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java @@ -42,7 +42,7 @@ import org.hibernate.mapping.Value; import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.query.ComparisonOperator; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.InFragment; import org.hibernate.sql.Insert; import org.hibernate.sql.SelectFragment; 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 936e85d6ff..f3acc29dd5 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 @@ -45,12 +45,13 @@ import org.hibernate.metamodel.mapping.StateArrayContributorMapping; import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.property.access.spi.Setter; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; import org.hibernate.sql.SelectFragment; +import org.hibernate.sql.SimpleSelect; import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; import org.hibernate.sql.ast.spi.SqlAstCreationContext; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.UnionTableGroup; diff --git a/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java b/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java index 998d8d0c5b..a6296f0211 100644 --- a/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java @@ -52,14 +52,13 @@ import org.hibernate.query.spi.AbstractQuery; import org.hibernate.query.spi.MutableQueryOptions; import org.hibernate.query.spi.QueryParameterBindings; import org.hibernate.query.spi.ScrollableResultsImplementor; +import org.hibernate.query.sqm.sql.internal.DomainResultProducer; import org.hibernate.result.NoMoreReturnsException; import org.hibernate.result.Output; import org.hibernate.result.ResultSetOutput; import org.hibernate.result.UpdateCountOutput; import org.hibernate.result.spi.ResultContext; -import org.hibernate.sql.exec.spi.DomainParameterBindingContext; import org.hibernate.sql.results.NoMoreOutputsException; -import org.hibernate.query.sqm.sql.internal.DomainResultProducer; import org.jboss.logging.Logger; @@ -70,7 +69,7 @@ import org.jboss.logging.Logger; */ public class ProcedureCallImpl extends AbstractQuery - implements ProcedureCallImplementor, ResultContext, DomainParameterBindingContext { + implements ProcedureCallImplementor, ResultContext { private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, ProcedureCallImpl.class.getName() @@ -229,31 +228,15 @@ public class ProcedureCallImpl return this; } - @Override - public DomainParameterBindingContext getDomainParameterBindingContext() { - return this; - } - @Override public QueryParameterBindings getParameterBindings() { return paramBindings; } - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // DomainParameterBindingContext - - - @Override public SessionFactoryImplementor getSessionFactory() { return getSession().getFactory(); } - @Override - public List getLoadIdentifiers() { - return Collections.emptyList(); - } - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Parameter registrations diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/spi/NamedHqlQueryMemento.java b/hibernate-core/src/main/java/org/hibernate/query/hql/spi/NamedHqlQueryMemento.java index 918519e406..fcc744da05 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/spi/NamedHqlQueryMemento.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/spi/NamedHqlQueryMemento.java @@ -15,14 +15,14 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl; import org.hibernate.query.named.AbstractNamedQueryMemento; import org.hibernate.query.named.NameableQuery; -import org.hibernate.query.named.NamedQueryMemento; +import org.hibernate.query.named.NamedQueryProducer; /** * NamedQueryMemento for HQL queries * * @author Steve Ebersole */ -public interface NamedHqlQueryMemento extends NamedQueryMemento { +public interface NamedHqlQueryMemento extends NamedQueryProducer { /** * Informational access to the HQL query string */ diff --git a/hibernate-core/src/main/java/org/hibernate/query/named/NamedQueryMemento.java b/hibernate-core/src/main/java/org/hibernate/query/named/NamedQueryMemento.java index 0ffb478a90..27226344fb 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/named/NamedQueryMemento.java +++ b/hibernate-core/src/main/java/org/hibernate/query/named/NamedQueryMemento.java @@ -12,6 +12,7 @@ import org.hibernate.CacheMode; import org.hibernate.FlushMode; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.query.spi.QueryEngine; +import org.hibernate.query.spi.QueryImplementor; import org.hibernate.query.spi.QueryParameterImplementor; /** diff --git a/hibernate-core/src/main/java/org/hibernate/query/named/NamedQueryProducer.java b/hibernate-core/src/main/java/org/hibernate/query/named/NamedQueryProducer.java new file mode 100644 index 0000000000..bb02102496 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/named/NamedQueryProducer.java @@ -0,0 +1,21 @@ +/* + * 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.named; + +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.query.spi.QueryImplementor; + +/** + * Specialization of NamedQueryMemento for mementos which can produce + * {@link org.hibernate.query.spi.QueryImplementor} implementations + * + * @author Steve Ebersole + */ +public interface NamedQueryProducer extends NamedQueryMemento { + QueryImplementor toQuery(SharedSessionContractImplementor session); + QueryImplementor toQuery(SharedSessionContractImplementor session, Class javaType); +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NamedNativeQueryMementoImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NamedNativeQueryMementoImpl.java index 3cdec599dc..b4b92a7545 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NamedNativeQueryMementoImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NamedNativeQueryMementoImpl.java @@ -107,7 +107,7 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple } @Override - public NativeQueryImplementor toQuery(SharedSessionContractImplementor session) { + public NativeQueryImplementor toQuery(SharedSessionContractImplementor session) { //noinspection unchecked return toQuery( session, (Class) null ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java index 8bef8f14e2..47d3c1795a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java @@ -15,7 +15,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; @@ -81,7 +80,6 @@ import org.hibernate.query.sql.spi.NonSelectInterpretationsKey; import org.hibernate.query.sql.spi.ParameterInterpretation; import org.hibernate.query.sql.spi.SelectInterpretationsKey; import org.hibernate.sql.exec.spi.Callback; -import org.hibernate.sql.exec.spi.DomainParameterBindingContext; import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.results.spi.JdbcValuesMappingProducer; import org.hibernate.sql.results.spi.RowTransformer; @@ -95,7 +93,7 @@ import static org.hibernate.jpa.QueryHints.HINT_NATIVE_LOCKMODE; @SuppressWarnings("WeakerAccess") public class NativeQueryImpl extends AbstractQuery - implements NativeQueryImplementor, DomainParameterBindingContext, ExecutionContext { + implements NativeQueryImplementor, ExecutionContext { private final String sqlString; private final ParameterMetadataImplementor parameterMetadata; @@ -225,27 +223,15 @@ public class NativeQueryImpl return queryOptions; } - @Override - public DomainParameterBindingContext getDomainParameterBindingContext() { - return this; - } - @Override public Callback getCallback() { throw new NotYetImplementedFor6Exception(); } - @Override public SessionFactoryImplementor getSessionFactory() { return getSession().getFactory(); } - @Override - public List getLoadIdentifiers() { - //noinspection unchecked - return (List) Collections.singletonList( collectionKey ); - } - @Override public QueryParameterBindings getQueryParameterBindings() { return parameterBindings; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java index 63d7f22a55..1d9397e72e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java @@ -14,6 +14,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.query.named.AbstractNamedQueryMemento; import org.hibernate.query.named.NamedQueryMemento; +import org.hibernate.query.named.NamedQueryProducer; import org.hibernate.query.sql.internal.NamedNativeQueryMementoImpl; /** @@ -21,7 +22,7 @@ import org.hibernate.query.sql.internal.NamedNativeQueryMementoImpl; * * @author Steve Ebersole */ -public interface NamedNativeQueryMemento extends NamedQueryMemento { +public interface NamedNativeQueryMemento extends NamedQueryProducer { /** * Informational access to the SQL query string */ @@ -35,7 +36,7 @@ public interface NamedNativeQueryMemento extends NamedQueryMemento { /** * Convert the memento into an untyped executable query */ - NativeQueryImplementor toQuery(SharedSessionContractImplementor session); + NativeQueryImplementor toQuery(SharedSessionContractImplementor session); /** * Convert the memento into a typed executable query diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java index b7384d2fd1..09f2614fee 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java @@ -167,7 +167,7 @@ public class ConcreteSqmSelectQueryPlan implements SelectQueryPlan { final SqmSelectToSqlAstConverter sqmConverter = sqmTranslatorFactory.createSelectConverter( executionContext.getQueryOptions(), domainParameterXref, - executionContext.getDomainParameterBindingContext().getQueryParameterBindings(), + executionContext.getQueryParameterBindings(), executionContext.getLoadQueryInfluencers(), sessionFactory ); @@ -189,7 +189,7 @@ public class ConcreteSqmSelectQueryPlan implements SelectQueryPlan { final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings( - executionContext.getDomainParameterBindingContext().getQueryParameterBindings(), + executionContext.getQueryParameterBindings(), domainParameterXref, jdbcParamsXref, // todo (6.0) : ugh. this one is important diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java index 228131b074..478cfc98ac 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java @@ -56,7 +56,6 @@ import org.hibernate.query.sqm.tree.select.SqmSelectStatement; import org.hibernate.query.sqm.tree.select.SqmSelection; import org.hibernate.query.sqm.tree.update.SqmUpdateStatement; import org.hibernate.sql.exec.spi.Callback; -import org.hibernate.sql.exec.spi.DomainParameterBindingContext; import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.type.BasicType; @@ -67,7 +66,7 @@ import org.hibernate.type.BasicType; */ public class QuerySqmImpl extends AbstractQuery - implements HqlQueryImplementor, ExecutionContext, DomainParameterBindingContext { + implements HqlQueryImplementor, ExecutionContext { private final String hqlString; private final SqmStatement sqmStatement; @@ -269,7 +268,6 @@ public class QuerySqmImpl } } - @Override public SessionFactoryImplementor getSessionFactory() { return getSession().getFactory(); } @@ -567,20 +565,11 @@ public class QuerySqmImpl return new UpdateQueryPlanImpl( sqmStatement, updateHandler, this ); } - @Override - public DomainParameterBindingContext getDomainParameterBindingContext() { - return this; - } - @Override public Callback getCallback() { return afterLoadAction -> {}; } - @Override - public List getLoadIdentifiers() { - return null; - } @Override public NamedHqlQueryMemento toMemento(String name) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmMappingModelHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmMappingModelHelper.java index fb0b616afd..75fbe99bb4 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmMappingModelHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmMappingModelHelper.java @@ -27,7 +27,7 @@ import org.hibernate.metamodel.spi.DomainMetamodel; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.query.sqm.SqmExpressable; import org.hibernate.query.sqm.SqmPathSource; -import org.hibernate.query.sqm.sql.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.domain.SqmPath; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java index 468afa00f2..5faf4c8a86 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java @@ -26,7 +26,7 @@ import org.hibernate.query.spi.QueryParameterBinding; import org.hibernate.query.spi.QueryParameterBindings; import org.hibernate.query.spi.QueryParameterImplementor; import org.hibernate.query.sqm.spi.JdbcParameterBySqmParameterAccess; -import org.hibernate.query.sqm.sql.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.query.sqm.tree.SqmDmlStatement; import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.query.sqm.tree.expression.SqmParameter; @@ -155,7 +155,9 @@ public class SqmUtil { Map, Map>> jdbcParamXref, SqlAstCreationState sqlAstCreationState, SharedSessionContractImplementor session) { - final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( domainParameterXref ); + final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( + domainParameterXref.getSqmParameterCount() + ); for ( Map.Entry, List> entry : domainParameterXref.getSqmParamByQueryParam().entrySet() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index 9cbcea0dda..bf28740370 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -96,8 +96,12 @@ import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.spi.FromClauseAccess; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; +import org.hibernate.sql.ast.spi.SqlAliasBaseManager; import org.hibernate.sql.ast.spi.SqlAstCreationContext; +import org.hibernate.sql.ast.spi.SqlAstProcessingState; +import org.hibernate.sql.ast.spi.SqlAstQuerySpecProcessingState; import org.hibernate.sql.ast.spi.SqlAstTreeHelper; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression; import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression; import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression; @@ -218,16 +222,6 @@ public abstract class BaseSqmToSqlAstConverter return sqlAliasBaseManager; } - @Override - public DomainParameterXref getDomainParameterXref() { - return domainParameterXref; - } - - @Override - public QueryParameterBindings getDomainParameterBindings() { - return domainParameterBindings; - } - @Override public LockMode determineLockMode(String identificationVariable) { return queryOptions.getLockOptions().getEffectiveLockMode( identificationVariable ); @@ -287,8 +281,7 @@ public abstract class BaseSqmToSqlAstConverter sqlQuerySpec, processingStateStack.getCurrent(), this, - currentClauseStack::getCurrent, - () -> (expression) -> {} + currentClauseStack::getCurrent ) ); @@ -742,7 +735,13 @@ public abstract class BaseSqmToSqlAstConverter this.jdbcParameters.addParameters( jdbcParametersForSqm ); this.jdbcParamsBySqmParam.put( sqmParameter, jdbcParametersForSqm ); - return new SqmParameterInterpretation( sqmParameter, jdbcParametersForSqm, valueMapping ); + return new SqmParameterInterpretation( + sqmParameter, + domainParameterXref.getQueryParameter( sqmParameter ), + jdbcParametersForSqm, + valueMapping, + domainParameterBindings::getBinding + ); } protected MappingModelExpressable determineValueMapping(SqmExpression sqmExpression) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmToSqlAstConverter.java index 8ac26dc88f..36e76fe54f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmToSqlAstConverter.java @@ -8,7 +8,7 @@ package org.hibernate.query.sqm.sql; import org.hibernate.internal.util.collections.Stack; import org.hibernate.query.sqm.SemanticQueryWalker; -import org.hibernate.query.sqm.sql.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.sql.ast.Clause; /** diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java index f2ec4d9655..cfb86ccb9e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java @@ -12,8 +12,8 @@ import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.metamodel.mapping.BasicValuedModelPart; import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.query.sqm.SemanticQueryWalker; -import org.hibernate.query.sqm.sql.SqlAstCreationState; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.sql.ast.spi.SqlAstCreationContext; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstProcessingStateImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstProcessingStateImpl.java index 114fdf4325..808cab5123 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstProcessingStateImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstProcessingStateImpl.java @@ -14,9 +14,9 @@ import java.util.function.Function; import java.util.function.Supplier; import org.hibernate.query.sqm.sql.ConversionException; -import org.hibernate.query.sqm.sql.SqlAstCreationState; -import org.hibernate.query.sqm.sql.SqlAstProcessingState; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlAstProcessingState; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.expression.Expression; @@ -34,19 +34,16 @@ public class SqlAstProcessingStateImpl implements SqlAstProcessingState, SqlExpr private final SqlAstProcessingState parentState; private final SqlAstCreationState creationState; private final Supplier currentClauseAccess; - private final Supplier> resolvedExpressionConsumerAccess; private final Map expressionMap = new HashMap<>(); public SqlAstProcessingStateImpl( SqlAstProcessingState parentState, SqlAstCreationState creationState, - Supplier currentClauseAccess, - Supplier> resolvedExpressionConsumerAccess) { + Supplier currentClauseAccess) { this.parentState = parentState; this.creationState = creationState; this.currentClauseAccess = currentClauseAccess; - this.resolvedExpressionConsumerAccess = resolvedExpressionConsumerAccess; } @@ -93,8 +90,6 @@ public class SqlAstProcessingStateImpl implements SqlAstProcessingState, SqlExpr final Expression result = normalize( expression ); - resolvedExpressionConsumerAccess.get().accept( result ); - return result; } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstQuerySpecProcessingStateImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstQuerySpecProcessingStateImpl.java index 106af497e3..0300423df0 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstQuerySpecProcessingStateImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqlAstQuerySpecProcessingStateImpl.java @@ -12,9 +12,9 @@ import java.util.function.Consumer; import java.util.function.Supplier; import org.hibernate.metamodel.mapping.MappingModelExpressable; -import org.hibernate.query.sqm.sql.SqlAstCreationState; -import org.hibernate.query.sqm.sql.SqlAstProcessingState; -import org.hibernate.query.sqm.sql.SqlAstQuerySpecProcessingState; +import org.hibernate.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlAstProcessingState; +import org.hibernate.sql.ast.spi.SqlAstQuerySpecProcessingState; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.spi.SqlAstWalker; import org.hibernate.sql.ast.spi.SqlSelection; @@ -37,9 +37,8 @@ public class SqlAstQuerySpecProcessingStateImpl QuerySpec querySpec, SqlAstProcessingState parent, SqlAstCreationState creationState, - Supplier currentClauseAccess, - Supplier> resolvedExpressionConsumerAccess) { - super( parent, creationState, currentClauseAccess, resolvedExpressionConsumerAccess ); + Supplier currentClauseAccess) { + super( parent, creationState, currentClauseAccess ); this.querySpec = querySpec; } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqmParameterInterpretation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqmParameterInterpretation.java index 28bc76a245..23fed0c9ae 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqmParameterInterpretation.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqmParameterInterpretation.java @@ -7,6 +7,7 @@ package org.hibernate.query.sqm.sql.internal; import java.util.List; +import java.util.function.Function; import org.hibernate.metamodel.mapping.MappingModelExpressable; import org.hibernate.metamodel.model.domain.AllowableParameterType; @@ -28,16 +29,22 @@ import org.hibernate.sql.results.spi.DomainResultCreationState; */ public class SqmParameterInterpretation implements Expression, DomainResultProducer { private final SqmParameter sqmParameter; + private final QueryParameterImplementor queryParameter; private final MappingModelExpressable valueMapping; + private final Function queryParameterBindingResolver; private final Expression resolvedExpression; public SqmParameterInterpretation( SqmParameter sqmParameter, + QueryParameterImplementor queryParameter, List jdbcParameters, - MappingModelExpressable valueMapping) { + MappingModelExpressable valueMapping, + Function queryParameterBindingResolver) { this.sqmParameter = sqmParameter; + this.queryParameter = queryParameter; this.valueMapping = valueMapping; + this.queryParameterBindingResolver = queryParameterBindingResolver; assert jdbcParameters != null; assert jdbcParameters.size() > 0; @@ -67,12 +74,7 @@ public class SqmParameterInterpretation implements Expression, DomainResultProdu AllowableParameterType nodeType = sqmParameter.getNodeType(); if ( nodeType == null ) { - final QueryParameterImplementor queryParameter = creationState.getSqlAstCreationState() - .getDomainParameterXref() - .getQueryParameter( sqmParameter ); - final QueryParameterBinding binding = creationState.getSqlAstCreationState() - .getDomainParameterBindings() - .getBinding( queryParameter ); + final QueryParameterBinding binding = queryParameterBindingResolver.apply( queryParameter ); nodeType = binding.getBindType(); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqmTupleInterpretation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqmTupleInterpretation.java index 79b966a77d..4cf9098098 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqmTupleInterpretation.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/SqmTupleInterpretation.java @@ -12,7 +12,7 @@ import java.util.List; import org.hibernate.metamodel.mapping.MappingModelExpressable; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.internal.SqmMappingModelHelper; -import org.hibernate.query.sqm.sql.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.expression.SqmTuple; import org.hibernate.sql.ast.tree.expression.Expression; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/StandardSqmSelectToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/StandardSqmSelectToSqlAstConverter.java index a48b8ff107..dc41d51f1c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/StandardSqmSelectToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/StandardSqmSelectToSqlAstConverter.java @@ -30,7 +30,7 @@ import org.hibernate.query.spi.QueryOptions; import org.hibernate.query.spi.QueryParameterBindings; import org.hibernate.query.sqm.internal.DomainParameterXref; import org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter; -import org.hibernate.query.sqm.sql.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.query.sqm.sql.SqmSelectToSqlAstConverter; import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; diff --git a/hibernate-core/src/main/java/org/hibernate/result/spi/ResultContext.java b/hibernate-core/src/main/java/org/hibernate/result/spi/ResultContext.java index ea727a395a..d816dea181 100644 --- a/hibernate-core/src/main/java/org/hibernate/result/spi/ResultContext.java +++ b/hibernate-core/src/main/java/org/hibernate/result/spi/ResultContext.java @@ -10,7 +10,6 @@ import java.util.Set; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.query.spi.QueryOptions; -import org.hibernate.sql.exec.spi.DomainParameterBindingContext; /** * @author Steve Ebersole @@ -21,6 +20,4 @@ public interface ResultContext { Set getSynchronizedQuerySpaces(); QueryOptions getQueryOptions(); - - DomainParameterBindingContext getDomainParameterBindingContext(); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstToJdbcOperationConverter.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstToJdbcOperationConverter.java index 05938018ec..4e6996e3aa 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstToJdbcOperationConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstToJdbcOperationConverter.java @@ -21,7 +21,7 @@ public class AbstractSqlAstToJdbcOperationConverter extends AbstractSqlAstWalker implements SqlAstToJdbcOperationConverter { - private final Set affectedTableNames = new HashSet<>(); + private final Set affectedTableExpressions = new HashSet<>(); protected AbstractSqlAstToJdbcOperationConverter(SessionFactoryImplementor sessionFactory) { super( sessionFactory ); @@ -33,16 +33,21 @@ public class AbstractSqlAstToJdbcOperationConverter } @Override - public Set getAffectedTableNames() { - return affectedTableNames; + public Set getAffectedTableExpressions() { + return affectedTableExpressions; } + @Override + protected void renderTableReference(TableReference tableReference) { + super.renderTableReference( tableReference ); + registerAffectedTable( tableReference ); + } protected void registerAffectedTable(TableReference tableReference) { registerAffectedTable( tableReference.getTableExpression() ); } protected void registerAffectedTable(String tableExpression) { - affectedTableNames.add( tableExpression ); + affectedTableExpressions.add( tableExpression ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlAliasBaseManager.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseManager.java similarity index 91% rename from hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlAliasBaseManager.java rename to hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseManager.java index 86ca714562..887a21be9b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlAliasBaseManager.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseManager.java @@ -4,14 +4,12 @@ * 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; +package org.hibernate.sql.ast.spi; import java.util.HashMap; import java.util.Map; import org.hibernate.sql.ast.SqlTreeCreationLogger; -import org.hibernate.sql.ast.spi.SqlAliasBase; -import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; /** * Helper used in creating unique SQL table aliases for a SQL AST diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlAstCreationState.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstCreationState.java similarity index 73% rename from hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlAstCreationState.java rename to hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstCreationState.java index 0487bfd72a..d162249686 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlAstCreationState.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstCreationState.java @@ -4,16 +4,11 @@ * 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; +package org.hibernate.sql.ast.spi; import java.util.List; import org.hibernate.LockMode; -import org.hibernate.query.spi.QueryParameterBindings; -import org.hibernate.query.sqm.internal.DomainParameterXref; -import org.hibernate.sql.ast.spi.FromClauseAccess; -import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; -import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.results.spi.Fetch; import org.hibernate.sql.results.spi.FetchParent; @@ -34,10 +29,6 @@ public interface SqlAstCreationState { SqlAliasBaseGenerator getSqlAliasBaseGenerator(); - DomainParameterXref getDomainParameterXref(); - - QueryParameterBindings getDomainParameterBindings(); - LockMode determineLockMode(String identificationVariable); /** diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlAstProcessingState.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstProcessingState.java similarity index 93% rename from hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlAstProcessingState.java rename to hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstProcessingState.java index 0076661c1e..b07bb0bca0 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlAstProcessingState.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstProcessingState.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.query.sqm.sql; +package org.hibernate.sql.ast.spi; /** * Generalized access to state information relative to the "current process" of diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlAstQuerySpecProcessingState.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstQuerySpecProcessingState.java similarity index 87% rename from hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlAstQuerySpecProcessingState.java rename to hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstQuerySpecProcessingState.java index 95d39f2d4d..d82e126b0b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlAstQuerySpecProcessingState.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstQuerySpecProcessingState.java @@ -4,11 +4,12 @@ * 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; +package org.hibernate.sql.ast.spi; import org.hibernate.sql.ast.tree.select.QuerySpec; /** + * SqlAstProcessingState specialization for * @author Steve Ebersole */ public interface SqlAstQuerySpecProcessingState extends SqlAstProcessingState { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstToJdbcOperationConverter.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstToJdbcOperationConverter.java index cee3ddfacc..6a02c9ef6d 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstToJdbcOperationConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstToJdbcOperationConverter.java @@ -18,5 +18,5 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators; * @author Steve Ebersole */ public interface SqlAstToJdbcOperationConverter extends SqlAstWalker, SqlTypeDescriptorIndicators { - Set getAffectedTableNames(); + Set getAffectedTableExpressions(); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlExpressionResolver.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java similarity index 96% rename from hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlExpressionResolver.java rename to hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java index 53bd4652a0..526a2c3e8f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqlExpressionResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java @@ -4,11 +4,10 @@ * 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; +package org.hibernate.sql.ast.spi; import java.util.function.Function; -import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstSelectTranslator.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstSelectTranslator.java index 6ba1511d5c..1afc2999b5 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstSelectTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstSelectTranslator.java @@ -44,7 +44,7 @@ public class StandardSqlAstSelectTranslator querySpec.getSelectClause().getSqlSelections(), Collections.emptyList() ), - getAffectedTableNames() + getAffectedTableExpressions() ); } @@ -63,7 +63,7 @@ public class StandardSqlAstSelectTranslator sqlAstSelect.getQuerySpec().getSelectClause().getSqlSelections(), sqlAstSelect.getDomainResultDescriptors() ), - sqlAstSelect.getAffectedTableExpressions() + getAffectedTableExpressions() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/AbstractLiteral.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/AbstractLiteral.java index 5893bbfbf7..33c6a7d18b 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/AbstractLiteral.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/AbstractLiteral.java @@ -12,7 +12,7 @@ import java.util.function.Consumer; import org.hibernate.metamodel.mapping.BasicValuedMapping; import org.hibernate.metamodel.mapping.JdbcMapping; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.query.sqm.sql.internal.DomainResultProducer; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.spi.SqlSelection; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/ColumnReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/ColumnReference.java index 4142db40f4..c192017fe0 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/ColumnReference.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/ColumnReference.java @@ -15,6 +15,7 @@ import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.MappingModelExpressable; import org.hibernate.sql.ast.spi.SqlAstWalker; import org.hibernate.sql.ast.spi.SqlSelection; +import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.results.internal.SqlSelectionImpl; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.spi.TypeConfiguration; @@ -50,6 +51,14 @@ public class ColumnReference implements Expression { this.jdbcMapping = jdbcMapping; } + public ColumnReference( + TableReference tableReference, + String columnExpression, + JdbcMapping jdbcMapping, + SessionFactoryImplementor sessionFactory) { + this( tableReference.getIdentificationVariable(), columnExpression, jdbcMapping, sessionFactory ); + } + public String getExpressionText() { return referenceExpression; } @@ -58,6 +67,10 @@ public class ColumnReference implements Expression { return getExpressionText(); } + public JdbcMapping getJdbcMapping() { + return jdbcMapping; + } + @Override public MappingModelExpressable getExpressionType() { return (MappingModelExpressable) jdbcMapping; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/RootTableGroupProducer.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/RootTableGroupProducer.java index 270d3baf51..1f686e5ee2 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/RootTableGroupProducer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/RootTableGroupProducer.java @@ -12,7 +12,7 @@ import java.util.function.Supplier; import org.hibernate.LockMode; import org.hibernate.metamodel.mapping.ModelPartContainer; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; import org.hibernate.sql.ast.spi.SqlAstCreationContext; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupJoinProducer.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupJoinProducer.java index fbbf06a6af..733882ab2d 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupJoinProducer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupJoinProducer.java @@ -8,7 +8,7 @@ package org.hibernate.sql.ast.tree.from; import org.hibernate.LockMode; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; import org.hibernate.sql.ast.spi.SqlAstCreationContext; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupProducer.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupProducer.java index 818a6f2fbd..f0ef0f2f5a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupProducer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupProducer.java @@ -7,7 +7,7 @@ package org.hibernate.sql.ast.tree.from; import org.hibernate.metamodel.mapping.ModelPartContainer; -import org.hibernate.query.sqm.sql.SqlAliasBaseManager; +import org.hibernate.sql.ast.spi.SqlAliasBaseManager; /** * Marker interface for anything which produces a TableGroup diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReferenceContributor.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReferenceContributor.java index a192882ac8..8c242a7510 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReferenceContributor.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReferenceContributor.java @@ -6,7 +6,7 @@ */ package org.hibernate.sql.ast.tree.from; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAstCreationContext; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcExecHelper.java b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcExecHelper.java new file mode 100644 index 0000000000..5bea0aec4a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcExecHelper.java @@ -0,0 +1,48 @@ +/* + * 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.sql.exec.internal; + +import org.hibernate.CacheMode; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.query.spi.QueryOptions; +import org.hibernate.sql.exec.spi.ExecutionContext; + +import static org.hibernate.internal.util.NullnessHelper.coalesceSuppliedValues; + +/** + * @author Steve Ebersole + */ +public class JdbcExecHelper { + /** + * Singleton access + */ + public static final JdbcExecHelper INSTANCE = new JdbcExecHelper(); + + private JdbcExecHelper() { + } + + public static CacheMode resolveCacheMode(ExecutionContext executionContext) { + return resolveCacheMode( executionContext.getQueryOptions(), executionContext.getSession() ); + } + + public static CacheMode resolveCacheMode(QueryOptions options, SharedSessionContractImplementor session) { + return coalesceSuppliedValues( + () -> options == null ? null : options.getCacheMode(), + session::getCacheMode, + () -> CacheMode.NORMAL + ); + } + + public static CacheMode resolveCacheMode(CacheMode override, SharedSessionContractImplementor session) { + return coalesceSuppliedValues( + () -> override, + session::getCacheMode, + () -> CacheMode.NORMAL + ); + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingsImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingsImpl.java index 86fe1b1433..fb9f4ffe72 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingsImpl.java @@ -25,9 +25,9 @@ import org.hibernate.sql.exec.spi.JdbcParameterBindings; public class JdbcParameterBindingsImpl implements JdbcParameterBindings { private Map bindingMap; - public JdbcParameterBindingsImpl(DomainParameterXref domainParameterXref) { - if ( domainParameterXref.getSqmParameterCount() > 0 ) { - bindingMap = new IdentityHashMap<>( domainParameterXref.getSqmParameterCount() ); + public JdbcParameterBindingsImpl(int expectedParameterCount) { + if ( expectedParameterCount > 0 ) { + bindingMap = new IdentityHashMap<>( expectedParameterCount ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcSelectExecutorStandardImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcSelectExecutorStandardImpl.java index 4af1bf2bdd..887044c2c6 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcSelectExecutorStandardImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcSelectExecutorStandardImpl.java @@ -218,7 +218,7 @@ public class JdbcSelectExecutorStandardImpl implements JdbcSelectExecutor { final List cachedResults; final boolean queryCacheEnabled = executionContext.getSession().getFactory().getSessionFactoryOptions().isQueryCacheEnabled(); - final CacheMode cacheMode = resolveCacheMode( executionContext ); + final CacheMode cacheMode = JdbcExecHelper.resolveCacheMode( executionContext ); final JdbcValuesMapping jdbcValuesMapping = jdbcSelect.getJdbcValuesMappingProducer() .resolve( resultSetAccess, executionContext.getSession().getFactory() ); @@ -241,7 +241,7 @@ public class JdbcSelectExecutorStandardImpl implements JdbcSelectExecutor { queryResultsCacheKey = QueryKey.from( jdbcSelect.getSql(), executionContext.getQueryOptions().getLimit(), - executionContext.getDomainParameterBindingContext().getQueryParameterBindings(), + executionContext.getQueryParameterBindings(), executionContext.getSession() ); @@ -287,17 +287,4 @@ public class JdbcSelectExecutorStandardImpl implements JdbcSelectExecutor { } } - private CacheMode resolveCacheMode(ExecutionContext executionContext) { - CacheMode cacheMode = executionContext.getQueryOptions().getCacheMode(); - if ( cacheMode != null ) { - return cacheMode; - } - - cacheMode = executionContext.getSession().getCacheMode(); - if ( cacheMode != null ) { - return cacheMode; - } - - return CacheMode.NORMAL; - } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/exec/spi/DomainParameterBindingContext.java b/hibernate-core/src/main/java/org/hibernate/sql/exec/spi/DomainParameterBindingContext.java deleted file mode 100644 index cf59b1cc9a..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/sql/exec/spi/DomainParameterBindingContext.java +++ /dev/null @@ -1,26 +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.sql.exec.spi; - -import java.util.List; - -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.query.spi.QueryParameterBindings; - -/** - * Contextual information for performing JDBC parameter binding. Generally - * speaking this is the source of all bind values in terms of the domain model - * - * @author Steve Ebersole - */ -public interface DomainParameterBindingContext { - SessionFactoryImplementor getSessionFactory(); - - List getLoadIdentifiers(); - - QueryParameterBindings getQueryParameterBindings(); -} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/exec/spi/ExecutionContext.java b/hibernate-core/src/main/java/org/hibernate/sql/exec/spi/ExecutionContext.java index c95588c5b8..7515c9ccca 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/exec/spi/ExecutionContext.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/exec/spi/ExecutionContext.java @@ -11,6 +11,7 @@ import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.query.spi.QueryOptions; +import org.hibernate.query.spi.QueryParameterBindings; /** * @author Steve Ebersole @@ -32,7 +33,7 @@ public interface ExecutionContext { return getSession().getLoadQueryInfluencers(); } - DomainParameterBindingContext getDomainParameterBindingContext(); + QueryParameterBindings getQueryParameterBindings(); Callback getCallback(); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/DeferredResultSetAccess.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/DeferredResultSetAccess.java index 2a2b523d4b..7fe2e62cfd 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/DeferredResultSetAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/DeferredResultSetAccess.java @@ -73,11 +73,13 @@ public class DeferredResultSetAccess extends AbstractResultSetAccess { preparedStatement = statementCreator.apply( sql ); // set options - if ( executionContext.getQueryOptions().getFetchSize() != null ) { - preparedStatement.setFetchSize( executionContext.getQueryOptions().getFetchSize() ); - } - if ( executionContext.getQueryOptions().getTimeout() != null ) { - preparedStatement.setQueryTimeout( executionContext.getQueryOptions().getTimeout() ); + if ( executionContext.getQueryOptions() != null ) { + if ( executionContext.getQueryOptions().getFetchSize() != null ) { + preparedStatement.setFetchSize( executionContext.getQueryOptions().getFetchSize() ); + } + if ( executionContext.getQueryOptions().getTimeout() != null ) { + preparedStatement.setQueryTimeout( executionContext.getQueryOptions().getTimeout() ); + } } // todo : limit/offset diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesResultSetImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesResultSetImpl.java index b27ba72e4c..fd7ef01d41 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesResultSetImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesResultSetImpl.java @@ -15,6 +15,7 @@ import org.hibernate.query.Limit; import org.hibernate.query.spi.QueryOptions; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.exec.ExecutionException; +import org.hibernate.sql.exec.internal.JdbcExecHelper; import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.results.internal.caching.QueryCachePutManager; import org.hibernate.sql.results.internal.caching.QueryCachePutManagerDisabledImpl; @@ -64,7 +65,7 @@ public class JdbcValuesResultSetImpl extends AbstractJdbcValues { } private static int interpretNumberOfRowsToProcess(QueryOptions queryOptions) { - if ( queryOptions.getLimit() == null ) { + if ( queryOptions == null || queryOptions.getLimit() == null ) { return -1; } final Limit limit = queryOptions.getLimit(); @@ -83,7 +84,7 @@ public class JdbcValuesResultSetImpl extends AbstractJdbcValues { .getFactory() .getSessionFactoryOptions() .isQueryCacheEnabled(); - final CacheMode cacheMode = queryOptions.getCacheMode(); + final CacheMode cacheMode = JdbcExecHelper.resolveCacheMode( executionContext ); if ( queryCacheEnabled && cacheMode.isPutEnabled() ) { final QueryResultsCache queryCache = executionContext.getSession().getFactory() diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/RowProcessingStateStandardImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/RowProcessingStateStandardImpl.java index 4f4c846de8..fb4d7ed2b4 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/RowProcessingStateStandardImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/RowProcessingStateStandardImpl.java @@ -9,13 +9,12 @@ package org.hibernate.sql.results.internal; import java.sql.SQLException; import java.util.List; -import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.plan.spi.EntityFetch; import org.hibernate.query.NavigablePath; import org.hibernate.query.spi.QueryOptions; +import org.hibernate.query.spi.QueryParameterBindings; import org.hibernate.sql.exec.spi.Callback; -import org.hibernate.sql.exec.spi.DomainParameterBindingContext; import org.hibernate.sql.results.spi.Initializer; import org.hibernate.sql.results.spi.JdbcValues; import org.hibernate.sql.results.spi.JdbcValuesSourceProcessingState; @@ -99,8 +98,8 @@ public class RowProcessingStateStandardImpl implements RowProcessingState { } @Override - public DomainParameterBindingContext getDomainParameterBindingContext() { - throw new NotYetImplementedFor6Exception(); + public QueryParameterBindings getQueryParameterBindings() { + return getJdbcValuesSourceProcessingState().getExecutionContext().getQueryParameterBindings(); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/domain/RootBiDirectionalFetchImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/domain/RootBiDirectionalFetchImpl.java index 7c6ea25349..2f96e6195b 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/domain/RootBiDirectionalFetchImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/domain/RootBiDirectionalFetchImpl.java @@ -86,6 +86,11 @@ public class RootBiDirectionalFetchImpl implements BiDirectionalFetch, Fetchable return null; } + @Override + public String getPartName() { + return navigablePath.getLocalName(); + } + @Override public JavaTypeDescriptor getJavaTypeDescriptor() { return referencedRoot.getResultJavaTypeDescriptor(); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultCreationState.java b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultCreationState.java index ede30d10f2..3d45213dbd 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultCreationState.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultCreationState.java @@ -9,8 +9,8 @@ package org.hibernate.sql.results.spi; import java.util.List; import org.hibernate.LockMode; -import org.hibernate.query.sqm.sql.SqlAliasBaseManager; -import org.hibernate.query.sqm.sql.SqlAstCreationState; +import org.hibernate.sql.ast.spi.SqlAliasBaseManager; +import org.hibernate.sql.ast.spi.SqlAstCreationState; /** * @author Steve Ebersole diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java index 15efed5b94..95b412574c 100644 --- a/hibernate-core/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java @@ -59,7 +59,7 @@ import org.hibernate.persister.spi.PersisterClassResolver; import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAstCreationContext; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/loading/LoadingSmokeTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/loading/LoadingSmokeTests.java index c37e5725fc..f744f6e9c6 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/loading/LoadingSmokeTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/loading/LoadingSmokeTests.java @@ -7,14 +7,10 @@ package org.hibernate.orm.test.loading; import org.hibernate.Hibernate; -import org.hibernate.boot.MetadataSources; -import org.hibernate.query.spi.QueryImplementor; -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; import org.hibernate.testing.orm.domain.StandardDomainModel; import org.hibernate.testing.orm.domain.gambit.BasicEntity; import org.hibernate.testing.orm.junit.DomainModel; -import org.hibernate.testing.orm.junit.FailureExpected; import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactoryFunctionalTesting; import org.hibernate.testing.orm.junit.SessionFactoryScope; @@ -24,12 +20,9 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Tags; import org.junit.jupiter.api.Test; -import org.hamcrest.MatcherAssert; - +import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author Steve Ebersole @@ -50,19 +43,20 @@ public class LoadingSmokeTests { session -> { final BasicEntity loaded = session.byId( BasicEntity.class ).getReference( 1 ); assertThat( loaded, notNullValue() ); - assertFalse( Hibernate.isInitialized( loaded ) ); + assertThat( Hibernate.isInitialized( loaded ), is( false ) ); } ); } @Test - @FailureExpected( reason = "read-by-position not yet implemented for loading" ) public void testBasicGet(SessionFactoryScope scope) { scope.inTransaction( session -> { final BasicEntity gotten = session.byId( BasicEntity.class ).load( 1 ); assertThat( gotten, notNullValue() ); - assertTrue( Hibernate.isInitialized( gotten ) ); + assertThat( Hibernate.isInitialized( gotten ), is( true ) ); + assertThat( gotten.getId(), is( 1 ) ); + assertThat( gotten.getData(), is( "first" ) ); } ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/ParameterTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/ParameterTests.java index 24f5bb7641..8ad77a7a39 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/ParameterTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/ParameterTests.java @@ -18,8 +18,6 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.hibernate.Session; -import org.hibernate.metamodel.model.domain.internal.BasicSqmPathSource; -import org.hibernate.metamodel.model.domain.internal.EmbeddedSqmPathSource; import org.hibernate.orm.test.query.sqm.BaseSqmUnitTest; import org.hibernate.query.Query; import org.hibernate.query.SemanticException; @@ -27,7 +25,7 @@ import org.hibernate.query.spi.QueryParameterBinding; import org.hibernate.query.spi.QueryParameterBindings; import org.hibernate.query.sqm.tree.expression.SqmParameter; import org.hibernate.query.sqm.tree.select.SqmSelectStatement; -import org.hibernate.sql.exec.spi.DomainParameterBindingContext; +import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.testing.orm.junit.ExpectedException; import org.hibernate.testing.orm.junit.ExpectedExceptionExtension; @@ -37,7 +35,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.hibernate.testing.hamcrest.CollectionMatchers.hasSize; @@ -103,7 +100,7 @@ public class ParameterTests extends BaseSqmUnitTest { query.setParameter( "start", Instant.now().minus( 7, ChronoUnit.DAYS ), TemporalType.TIMESTAMP ); query.setParameter( "end", Instant.now().plus( 7, ChronoUnit.DAYS ), TemporalType.TIMESTAMP ); - final QueryParameterBindings bindings = ( (DomainParameterBindingContext) query ).getQueryParameterBindings(); + final QueryParameterBindings bindings = ( (ExecutionContext) query ).getQueryParameterBindings(); final QueryParameterBinding startBinding = bindings.getBinding( "start" ); assertThat( startBinding.getExplicitTemporalPrecision(), equalTo( TemporalType.TIMESTAMP ) ); @@ -121,7 +118,7 @@ public class ParameterTests extends BaseSqmUnitTest { query.setParameter( "start", Instant.now().minus( 7, ChronoUnit.DAYS ), TemporalType.DATE ); query.setParameter( "end", Instant.now().plus( 7, ChronoUnit.DAYS ), TemporalType.DATE ); - final QueryParameterBindings bindings = ( (DomainParameterBindingContext) query ).getQueryParameterBindings(); + final QueryParameterBindings bindings = ( (ExecutionContext) query ).getQueryParameterBindings(); final QueryParameterBinding startBinding = bindings.getBinding( "start" ); assertThat( startBinding.getExplicitTemporalPrecision(), equalTo( TemporalType.DATE ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java index 0fd589e95a..85adeebdd8 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java +++ b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java @@ -59,7 +59,7 @@ import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.persister.walking.spi.CollectionElementDefinition; import org.hibernate.persister.walking.spi.CollectionIndexDefinition; import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAstCreationContext; diff --git a/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java b/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java index f7c23bb04f..9d1d1af71f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java +++ b/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java @@ -60,7 +60,7 @@ import org.hibernate.persister.entity.MultiLoadOptions; import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; -import org.hibernate.query.sqm.sql.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAstCreationContext;