preliminary work on replacing LoadPlan with SQL AST approach - basic working support

This commit is contained in:
Steve Ebersole 2019-11-06 13:24:07 -06:00
parent 704ba4f85f
commit e522cbe542
91 changed files with 1784 additions and 432 deletions

View File

@ -179,7 +179,9 @@ cleanEclipse {
project.delete '.externalToolBuilders' project.delete '.externalToolBuilders'
project.delete 'hibernate-core-RunnableIdeTest.launch' project.delete 'hibernate-core-RunnableIdeTest.launch'
} }
tasks.eclipse.dependsOn(cleanEclipse) tasks.eclipse.dependsOn(cleanEclipse)
eclipse { eclipse {
project { project {
file { file {

View File

@ -77,7 +77,7 @@ public class NullnessHelper {
return value; return value;
} }
} }
else { else if ( value != null ) {
return value; return value;
} }
} }

View File

@ -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<JdbcParameter> 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<DomainResult> 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<String> 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<JdbcParameter> 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;
}
}

View File

@ -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<FetchParent, LoaderSqlAstCreationState, List<Fetch>> fetchProcessor;
public LoaderSqlAstCreationState(
QuerySpec querySpec,
SqlAliasBaseManager sqlAliasBaseManager,
FromClauseAccess fromClauseAccess,
LockOptions lockOptions,
BiFunction<FetchParent, LoaderSqlAstCreationState, List<Fetch>> 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<Fetch> 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<String> getDatabaseHints() {
return null;
}
@Override
public Integer getFetchSize() {
return null;
}
@Override
public Limit getLimit() {
return null;
}
}

View File

@ -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<JdbcParameter> getJdbcParameters();
}
@SuppressWarnings("WeakerAccess")
public static SqlAstDescriptor createSelect(
SessionFactoryImplementor sessionFactory,
Loadable loadable,
List<ModelPart> 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<ModelPart> 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<ModelPart> 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<String> affectedTables = new HashSet<>();
final List<DomainResult> 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<JdbcParameter> 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<JdbcParameter> 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<ColumnReference> 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<JdbcParameter> 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<Fetch> visitFetches(FetchParent fetchParent, LoaderSqlAstCreationState creationState) {
log.tracef( "Starting visitation of FetchParent's Fetchables : %s", fetchParent.getNavigablePath() );
final List<Fetch> fetches = new ArrayList<>();
final Consumer<Fetchable> 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<JdbcParameter> jdbcParameters;
public SqlAstDescriptorImpl(
SelectStatement sqlAst,
List<JdbcParameter> jdbcParameters) {
this.sqlAst = sqlAst;
this.jdbcParameters = jdbcParameters;
}
@Override
public SelectStatement getSqlAst() {
return sqlAst;
}
@Override
public List<JdbcParameter> getJdbcParameters() {
return jdbcParameters;
}
}

View File

@ -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<T> extends SingleIdEntityLoaderSupport<T> {
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" );
}
}

View File

@ -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<T> extends SingleIdEntityLoaderSupport<T> {
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" );
}
}

View File

@ -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<T> extends SingleIdEntityLoaderSupport<T> 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" );
}
}

View File

@ -7,10 +7,14 @@
package org.hibernate.loader.internal; package org.hibernate.loader.internal;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.loader.spi.SingleIdEntityLoader; 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 * Implementation of SingleIdEntityLoader for cases where the application has
@ -19,22 +23,50 @@ import org.hibernate.persister.entity.EntityPersister;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class SingleIdEntityLoaderProvidedQueryImpl<T> implements SingleIdEntityLoader<T> { public class SingleIdEntityLoaderProvidedQueryImpl<T> implements SingleIdEntityLoader<T> {
private final EntityPersister entityDescriptor; private final EntityMappingType entityDescriptor;
private final String loadQueryName; private final NamedQueryProducer namedQueryMemento;
public SingleIdEntityLoaderProvidedQueryImpl(EntityPersister entityDescriptor, String loadQueryName) { public SingleIdEntityLoaderProvidedQueryImpl(
EntityMappingType entityDescriptor,
String loadQueryName,
SessionFactoryImplementor sessionFactory) {
this.entityDescriptor = entityDescriptor; 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 @Override
public EntityPersister getLoadable() { public EntityMappingType getLoadable() {
return entityDescriptor; return entityDescriptor;
} }
@Override @Override
public T load(Object pkValue, LockOptions lockOptions, SharedSessionContractImplementor session) { public T load(Object pkValue, LockOptions lockOptions, SharedSessionContractImplementor session) {
throw new NotYetImplementedFor6Exception( getClass() ); //noinspection unchecked
final QueryImplementor<T> query = namedQueryMemento.toQuery(
session,
entityDescriptor.getMappedJavaTypeDescriptor().getJavaType()
);
query.setParameter( 0, pkValue );
return query.uniqueResult();
} }
@Override @Override

View File

@ -6,81 +6,56 @@
*/ */
package org.hibernate.loader.internal; package org.hibernate.loader.internal;
import java.io.Serializable;
import java.util.EnumMap; import java.util.EnumMap;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.loader.entity.BatchingEntityLoaderBuilder;
import org.hibernate.loader.spi.InternalFetchProfile; 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.EntityPersister;
import org.hibernate.persister.entity.OuterJoinLoadable;
import org.hibernate.sql.exec.spi.JdbcSelect;
/** /**
* Standard implementation of SingleIdEntityLoader * Standard implementation of SingleIdEntityLoader
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class SingleIdEntityLoaderStandardImpl<T> implements SingleIdEntityLoader<T>, Preparable { public class SingleIdEntityLoaderStandardImpl<T> extends SingleIdEntityLoaderSupport<T> implements Preparable {
private final EntityPersister entityDescriptor; private EnumMap<LockMode, SingleIdLoadPlan> selectByLockMode = new EnumMap<>( LockMode.class );
private EnumMap<InternalFetchProfile, SingleIdLoadPlan> selectByInternalCascadeProfile;
private EnumMap<LockMode, JdbcSelect> selectByLockMode = new EnumMap<>( LockMode.class ); public SingleIdEntityLoaderStandardImpl(
private EnumMap<InternalFetchProfile,JdbcSelect> selectByInternalCascadeProfile; EntityMappingType entityDescriptor,
SessionFactoryImplementor sessionFactory) {
public SingleIdEntityLoaderStandardImpl(EntityPersister entityDescriptor) { super( entityDescriptor, sessionFactory );
this.entityDescriptor = entityDescriptor;
}
public void prepare() {
// see `org.hibernate.persister.entity.AbstractEntityPersister#createLoaders`
} }
@Override @Override
public EntityPersister getLoadable() { public void prepare() {
return entityDescriptor; // see `org.hibernate.persister.entity.AbstractEntityPersister#createLoaders`
} }
@Override @Override
public T load(Object key, LockOptions lockOptions, SharedSessionContractImplementor session) { public T load(Object key, LockOptions lockOptions, SharedSessionContractImplementor session) {
// todo (6.0) : TEMPORARY - use the legacy loaders final SingleIdLoadPlan<T> loadPlan = resolveLoadPlan( lockOptions, session );
//noinspection unchecked return loadPlan.load( key, lockOptions, session );
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() );
} }
@Override private SingleIdLoadPlan<T> resolveLoadPlan(
public Object[] loadDatabaseSnapshot(Object id, SharedSessionContractImplementor session) {
throw new NotYetImplementedFor6Exception( getClass() );
}
private JdbcSelect resolveJdbcSelect(
LockOptions lockOptions, LockOptions lockOptions,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
final LoadQueryInfluencers loadQueryInfluencers = session.getLoadQueryInfluencers(); 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. // 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 // 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 // properly restrict the SQL/JDBC results. For this reason it has higher
// precedence than even "internal" fetch profiles. // precedence than even "internal" fetch profiles.
return createJdbcSelect( lockOptions, loadQueryInfluencers, session.getFactory() ); return createLoadPlan( lockOptions, loadQueryInfluencers, session.getFactory() );
} }
final InternalFetchProfile enabledInternalFetchProfile = loadQueryInfluencers.getEnabledInternalFetchProfile(); final InternalFetchProfile enabledInternalFetchProfile = loadQueryInfluencers.getEnabledInternalFetchProfile();
@ -89,34 +64,56 @@ public class SingleIdEntityLoaderStandardImpl<T> implements SingleIdEntityLoader
if ( selectByInternalCascadeProfile == null ) { if ( selectByInternalCascadeProfile == null ) {
selectByInternalCascadeProfile = new EnumMap<>( InternalFetchProfile.class ); selectByInternalCascadeProfile = new EnumMap<>( InternalFetchProfile.class );
} }
return selectByInternalCascadeProfile.computeIfAbsent( else {
loadQueryInfluencers.getEnabledInternalFetchProfile(), final SingleIdLoadPlan existing = selectByInternalCascadeProfile.get( enabledInternalFetchProfile );
internalFetchProfileType -> createJdbcSelect( lockOptions, loadQueryInfluencers, session.getFactory() ) if ( existing != null ) {
//noinspection unchecked
return existing;
}
}
final SingleIdLoadPlan<T> 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 // 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 // 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 ) { if ( reusable ) {
return selectByLockMode.computeIfAbsent( final SingleIdLoadPlan existing = selectByLockMode.get( lockOptions.getLockMode() );
lockOptions.getLockMode(), if ( existing != null ) {
lockMode -> createJdbcSelect( lockOptions, loadQueryInfluencers, session.getFactory() ) //noinspection unchecked
return existing;
}
final SingleIdLoadPlan<T> 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) { private boolean determineIfReusable(LockOptions lockOptions, LoadQueryInfluencers loadQueryInfluencers) {
if ( entityDescriptor.isAffectedByEntityGraph( loadQueryInfluencers ) ) { if ( getLoadable().isAffectedByEntityGraph( loadQueryInfluencers ) ) {
return false; return false;
} }
if ( entityDescriptor.isAffectedByEnabledFetchProfiles( loadQueryInfluencers ) ) { if ( getLoadable().isAffectedByEnabledFetchProfiles( loadQueryInfluencers ) ) {
return false; return false;
} }
@ -128,23 +125,24 @@ public class SingleIdEntityLoaderStandardImpl<T> implements SingleIdEntityLoader
return true; return true;
} }
private JdbcSelect createJdbcSelect( private SingleIdLoadPlan<T> createLoadPlan(
LockOptions lockOptions, LockOptions lockOptions,
LoadQueryInfluencers queryInfluencers, LoadQueryInfluencers queryInfluencers,
SessionFactoryImplementor sessionFactory) { 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( return new SingleIdLoadPlan<>(
// entityDescriptor.getFactory(), getLoadable().getIdentifierMapping(),
// entityDescriptor sqlAstDescriptor
// ); );
// final SqlAstSelectDescriptor selectDescriptor = selectBuilder
// .generateSelectStatement( 1, queryInfluencers, lockOptions );
//
//
// return SqlAstSelectToJdbcSelectConverter.interpret(
// selectDescriptor,
// sessionFactory
// );
} }
} }

View File

@ -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<T> implements SingleIdEntityLoader<T> {
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 );
}
}

View File

@ -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<T> {
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<JdbcParameter> 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 );
}
}

View File

@ -14,7 +14,7 @@ import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.query.NavigablePath; 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.JoinType;
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;
@ -36,6 +36,8 @@ public interface Loadable extends ModelPart, RootTableGroupProducer {
boolean isAffectedByEntityGraph(LoadQueryInfluencers influencers); boolean isAffectedByEntityGraph(LoadQueryInfluencers influencers);
boolean isAffectedByEnabledFetchProfiles(LoadQueryInfluencers influencers); boolean isAffectedByEnabledFetchProfiles(LoadQueryInfluencers influencers);
String getPathName();
@Override @Override
default TableGroup createRootTableGroup( default TableGroup createRootTableGroup(
NavigablePath navigablePath, NavigablePath navigablePath,

View File

@ -8,6 +8,7 @@ package org.hibernate.loader.spi;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
/** /**
@ -17,7 +18,7 @@ import org.hibernate.persister.entity.EntityPersister;
*/ */
public interface SingleEntityLoader<T> extends Loader { public interface SingleEntityLoader<T> extends Loader {
@Override @Override
EntityPersister getLoadable(); EntityMappingType getLoadable();
/** /**
* Load an entity by a primary or unique key value. * Load an entity by a primary or unique key value.

View File

@ -16,6 +16,11 @@ import org.hibernate.property.access.spi.PropertyAccess;
public interface AttributeMapping extends ModelPart, ValueMapping { public interface AttributeMapping extends ModelPart, ValueMapping {
String getAttributeName(); String getAttributeName();
@Override
default String getPartName() {
return getAttributeName();
}
AttributeMetadataAccess getAttributeMetadataAccess(); AttributeMetadataAccess getAttributeMetadataAccess();
ManagedMappingType getDeclaringType(); ManagedMappingType getDeclaringType();

View File

@ -44,5 +44,10 @@ public interface CollectionPart extends ModelPart, Fetchable {
Nature getNature(); Nature getNature();
ModelPart getPartTypeDescriptor(); MappingType getPartTypeDescriptor();
@Override
default String getPartName() {
return getNature().getName();
}
} }

View File

@ -175,6 +175,11 @@ public class EmbeddableMappingType implements ManagedMappingType {
return representationStrategy; return representationStrategy;
} }
@Override
public String getPartName() {
return getEmbeddedValueMapping().getPartName();
}
@Override @Override
public <T> DomainResult<T> createDomainResult( public <T> DomainResult<T> createDomainResult(
NavigablePath navigablePath, NavigablePath navigablePath,
@ -248,10 +253,8 @@ public class EmbeddableMappingType implements ManagedMappingType {
Consumer<JdbcMapping> action, Consumer<JdbcMapping> action,
Clause clause, Clause clause,
TypeConfiguration typeConfiguration) { TypeConfiguration typeConfiguration) {
visitAttributeMappings( attributeMappings.forEach(
attributeMapping -> { (s, attributeMapping) -> attributeMapping.visitJdbcTypes( action, clause, typeConfiguration )
attributeMapping.visitJdbcTypes( action, clause, typeConfiguration );
}
); );
} }
@ -273,9 +276,11 @@ public class EmbeddableMappingType implements ManagedMappingType {
public void visitJdbcValues( public void visitJdbcValues(
Object value, Object value,
Clause clause, Clause clause,
JdbcValuesConsumer valuesConsumer, JdbcValuesConsumer consumer,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
throw new NotYetImplementedFor6Exception( getClass() ); attributeMappings.forEach(
(s, attributeMapping) -> attributeMapping.visitJdbcValues( value, clause, consumer, session )
);
} }
@Override @Override

View File

@ -8,7 +8,7 @@ package org.hibernate.metamodel.mapping;
import java.util.List; 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.query.sqm.sql.SqmToSqlAstConverter;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Expression;

View File

@ -11,4 +11,9 @@ package org.hibernate.metamodel.mapping;
*/ */
public interface EntityDiscriminatorMapping extends VirtualModelPart, BasicValuedModelPart { public interface EntityDiscriminatorMapping extends VirtualModelPart, BasicValuedModelPart {
String ROLE_NAME = "{discriminator}"; String ROLE_NAME = "{discriminator}";
@Override
default String getPartName() {
return ROLE_NAME;
}
} }

View File

@ -15,4 +15,9 @@ public interface EntityIdentifierMapping extends ValueMapping, ModelPart {
String ROLE_LOCAL_NAME = "{id}"; String ROLE_LOCAL_NAME = "{id}";
PropertyAccess getPropertyAccess(); PropertyAccess getPropertyAccess();
@Override
default String getPartName() {
return ROLE_LOCAL_NAME;
}
} }

View File

@ -9,12 +9,25 @@ package org.hibernate.metamodel.mapping;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier;
import org.hibernate.LockMode;
import org.hibernate.NotYetImplementedFor6Exception; 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.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.DomainResultAssembler;
import org.hibernate.sql.results.spi.Fetchable;
import org.hibernate.sql.results.spi.RowProcessingState; import org.hibernate.sql.results.spi.RowProcessingState;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import static org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer.UNFETCHED_PROPERTY; 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 * @author Steve Ebersole
*/ */
public interface EntityMappingType extends ManagedMappingType { public interface EntityMappingType extends ManagedMappingType, Loadable {
/** /**
* Safety-net. * Safety-net.
* *
@ -33,15 +46,30 @@ public interface EntityMappingType extends ManagedMappingType {
*/ */
EntityPersister getEntityPersister(); EntityPersister getEntityPersister();
default String getEntityName() { String getEntityName();
return getEntityPersister().getEntityName();
@Override
default String getPartName() {
return getEntityName();
}
@Override
default String getPathName() {
return getEntityName();
}
@Override
default JavaTypeDescriptor getJavaTypeDescriptor() {
return getMappedJavaTypeDescriptor();
} }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Inheritance // Inheritance
default AttributeMapping findDeclaredAttributeMapping(String name) { 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(); EntityVersionMapping getVersionMapping();
default EntityDiscriminatorMapping getDiscriminatorMapping() { default EntityDiscriminatorMapping getDiscriminatorMapping() {
return null; throw new NotYetImplementedFor6Exception( getClass() );
} }
NaturalIdMapping getNaturalIdMapping(); NaturalIdMapping getNaturalIdMapping();
@ -157,4 +185,80 @@ public interface EntityMappingType extends ManagedMappingType {
attributeMapping -> mappingConsumer.accept( (StateArrayContributorMapping) attributeMapping ) 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<Consumer<Predicate>> 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<AttributeMapping> 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();
}
} }

View File

@ -87,8 +87,8 @@ public interface EntityValuedModelPart extends FetchableContainer {
default void visitJdbcValues( default void visitJdbcValues(
Object value, Object value,
Clause clause, Clause clause,
JdbcValuesConsumer valuesConsumer, JdbcValuesConsumer consumer,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
getEntityMappingType().visitJdbcValues( value, clause, valuesConsumer, session ); getEntityMappingType().visitJdbcValues( value, clause, consumer, session );
} }
} }

View File

@ -11,6 +11,7 @@ import java.util.function.Consumer;
import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.sql.results.spi.FetchableContainer; 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 * 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 * @author Steve Ebersole
*/ */
public interface ManagedMappingType extends MappingType, FetchableContainer { public interface ManagedMappingType extends MappingType, FetchableContainer {
@Override
default JavaTypeDescriptor getJavaTypeDescriptor() {
return getMappedJavaTypeDescriptor();
}
/** /**
* Get the number of attributes defined on this class and any supers * Get the number of attributes defined on this class and any supers

View File

@ -13,11 +13,6 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface MappingType extends ModelPart { public interface MappingType {
JavaTypeDescriptor getMappedJavaTypeDescriptor(); JavaTypeDescriptor getMappedJavaTypeDescriptor();
@Override
default JavaTypeDescriptor getJavaTypeDescriptor() {
return getMappedJavaTypeDescriptor();
}
} }

View File

@ -6,16 +6,24 @@
*/ */
package org.hibernate.metamodel.mapping; package org.hibernate.metamodel.mapping;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.NavigablePath; 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.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.DomainResult;
import org.hibernate.sql.results.spi.DomainResultCreationState; import org.hibernate.sql.results.spi.DomainResultCreationState;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer; import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; 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 * an attribute, an entity identifier, collection elements, etc
* *
* @see DomainResultProducer * @see DomainResultProducer
@ -28,6 +36,8 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
public interface ModelPart extends MappingModelExpressable { public interface ModelPart extends MappingModelExpressable {
JavaTypeDescriptor getJavaTypeDescriptor(); JavaTypeDescriptor getJavaTypeDescriptor();
String getPartName();
/** /**
* Create a DomainResult for a specific reference to this ModelPart. * Create a DomainResult for a specific reference to this ModelPart.
*/ */
@ -48,4 +58,32 @@ public interface ModelPart extends MappingModelExpressable {
DomainResultCreationState creationState) { DomainResultCreationState creationState) {
throw new NotYetImplementedFor6Exception( getClass() ); 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<SqlSelection,JdbcMapping> 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);
}
} }

View File

@ -19,7 +19,7 @@ import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.query.NavigablePath; 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.spi.SqlSelection;
import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroup;

View File

@ -20,8 +20,8 @@ import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.sql.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.query.sqm.sql.SqlExpressionResolver; import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.ColumnReference;

View File

@ -10,8 +10,8 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor; import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.sql.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.query.sqm.sql.SqlExpressionResolver; import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;
import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.ColumnReference;

View File

@ -26,14 +26,14 @@ import org.hibernate.metamodel.mapping.SingularAttributeMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess; import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.query.NavigablePath; 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.query.sqm.sql.SqmToSqlAstConverter;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.JoinType;
import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBase;
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; 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.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.SqlTuple; import org.hibernate.sql.ast.tree.expression.SqlTuple;
@ -128,6 +128,15 @@ public class EmbeddedAttributeMapping
getEmbeddableTypeDescriptor().visitJdbcValues( value, clause, valuesConsumer, session ); 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 @Override
public <T> DomainResult<T> createDomainResult( public <T> DomainResult<T> createDomainResult(
NavigablePath navigablePath, NavigablePath navigablePath,

View File

@ -21,8 +21,8 @@ import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.metamodel.mapping.SingularAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.sql.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.query.sqm.sql.SqlExpressionResolver; import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.JoinType;

View File

@ -15,8 +15,8 @@ import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.sql.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
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.spi.SqlSelection;
import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroup;

View File

@ -68,9 +68,9 @@ import org.hibernate.persister.entity.OuterJoinLoadable;
import org.hibernate.persister.walking.internal.FetchStrategyHelper; import org.hibernate.persister.walking.internal.FetchStrategyHelper;
import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlAliasStemHelper; 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.spi.SqlSelection;
import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Expression;

View File

@ -24,8 +24,8 @@ import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.sql.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
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.JoinType;
import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBase;
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;

View File

@ -9,8 +9,8 @@ package org.hibernate.metamodel.mapping.internal;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.sql.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
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.spi.SqlSelection;
import org.hibernate.sql.ast.tree.expression.ColumnReference; import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroup;

View File

@ -6,33 +6,10 @@
*/ */
package org.hibernate.metamodel.model.domain.internal; 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.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.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel; import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType; 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 * Helper containing utilities useful for domain model handling

View File

@ -85,7 +85,7 @@ import org.hibernate.persister.walking.spi.CompositeCollectionElementDefinition;
import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.persister.walking.spi.EntityDefinition;
import org.hibernate.pretty.MessageHelper; 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.Alias;
import org.hibernate.sql.SelectFragment; import org.hibernate.sql.SelectFragment;
import org.hibernate.sql.SimpleSelect; import org.hibernate.sql.SimpleSelect;

View File

@ -28,7 +28,7 @@ import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.metamodel.model.domain.NavigableRole; import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.CollectionDefinition; 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.JoinType;
import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBase;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;

View File

@ -107,14 +107,18 @@ import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.jdbc.Expectation; import org.hibernate.jdbc.Expectation;
import org.hibernate.jdbc.Expectations; import org.hibernate.jdbc.Expectations;
import org.hibernate.jdbc.TooManyRowsAffectedException; import org.hibernate.jdbc.TooManyRowsAffectedException;
import org.hibernate.loader.BatchFetchStyle;
import org.hibernate.loader.custom.sql.SQLQueryParser; import org.hibernate.loader.custom.sql.SQLQueryParser;
import org.hibernate.loader.entity.BatchingEntityLoaderBuilder; import org.hibernate.loader.entity.BatchingEntityLoaderBuilder;
import org.hibernate.loader.entity.CascadeEntityLoader; import org.hibernate.loader.entity.CascadeEntityLoader;
import org.hibernate.loader.entity.EntityLoader; import org.hibernate.loader.entity.EntityLoader;
import org.hibernate.loader.entity.UniqueEntityLoader; import org.hibernate.loader.entity.UniqueEntityLoader;
import org.hibernate.loader.internal.SingleIdEntityLoaderDynamicBatch;
import org.hibernate.loader.internal.MultiIdEntityLoaderStandardImpl; import org.hibernate.loader.internal.MultiIdEntityLoaderStandardImpl;
import org.hibernate.loader.internal.NaturalIdLoaderStandardImpl; import org.hibernate.loader.internal.NaturalIdLoaderStandardImpl;
import org.hibernate.loader.internal.Preparable; 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.SingleIdEntityLoaderProvidedQueryImpl;
import org.hibernate.loader.internal.SingleIdEntityLoaderStandardImpl; import org.hibernate.loader.internal.SingleIdEntityLoaderStandardImpl;
import org.hibernate.loader.spi.Loader; 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.property.access.spi.Setter;
import org.hibernate.query.ComparisonOperator; import org.hibernate.query.ComparisonOperator;
import org.hibernate.query.NavigablePath; 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.Alias;
import org.hibernate.sql.Delete; import org.hibernate.sql.Delete;
import org.hibernate.sql.Insert; import org.hibernate.sql.Insert;
@ -229,6 +233,10 @@ public abstract class AbstractEntityPersister
private final String sqlAliasStem; 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<String> affectingFetchProfileNames = new HashSet<>(); private final Set<String> affectingFetchProfileNames = new HashSet<>();
private final SingleIdEntityLoader singleIdEntityLoader;
private final MultiIdEntityLoader multiIdEntityLoader;
private final NaturalIdLoader naturalIdLoader;
private final Map uniqueKeyLoaders = new HashMap(); private final Map uniqueKeyLoaders = new HashMap();
private final Map lockers = new HashMap(); private final Map lockers = new HashMap();
@ -681,11 +686,17 @@ public abstract class AbstractEntityPersister
rowIdName = bootDescriptor.getRootTable().getRowId(); rowIdName = bootDescriptor.getRootTable().getRowId();
if ( bootDescriptor.getLoaderName() != null ) { 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 { else {
singleIdEntityLoader = new SingleIdEntityLoaderStandardImpl( this ); singleIdEntityLoader = new SingleIdEntityLoaderStandardImpl( this, factory );
} }
multiIdEntityLoader = new MultiIdEntityLoaderStandardImpl( this ); 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") @SuppressWarnings("RedundantIfStatement")
private boolean determineWhetherToInvalidateCache( private boolean determineWhetherToInvalidateCache(
PersistentClass persistentClass, PersistentClass persistentClass,
@ -1146,6 +1179,11 @@ public abstract class AbstractEntityPersister
return sqlAliasStem; return sqlAliasStem;
} }
@Override
public String getPartName() {
return getEntityName();
}
@Override @Override
public <T> DomainResult<T> createDomainResult( public <T> DomainResult<T> createDomainResult(
NavigablePath navigablePath, NavigablePath navigablePath,
@ -1777,66 +1815,8 @@ public abstract class AbstractEntityPersister
return select; return select;
} }
public Object[] getDatabaseSnapshot(Serializable id, SharedSessionContractImplementor session) public Object[] getDatabaseSnapshot(Serializable id, SharedSessionContractImplementor session) throws HibernateException {
throws HibernateException { return singleIdEntityLoader.loadDatabaseSnapshot( id, session );
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()
);
}
} }
@Override @Override
@ -5247,6 +5227,10 @@ public abstract class AbstractEntityPersister
if ( entity instanceof SelfDirtinessTracker ) { if ( entity instanceof SelfDirtinessTracker ) {
( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes(); ( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes();
} }
if ( singleIdEntityLoader instanceof Preparable ) {
( (Preparable) singleIdEntityLoader ).prepare();
}
} }
public String[] getPropertyNames() { public String[] getPropertyNames() {

View File

@ -38,13 +38,8 @@ import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.spi.EntityRepresentationStrategy; import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.persister.walking.spi.EntityDefinition;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy; 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.SqlAliasStemHelper;
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
import org.hibernate.sql.ast.tree.from.RootTableGroupProducer; 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.EntityMetamodel;
import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.Type; import org.hibernate.type.Type;

View File

@ -6,6 +6,15 @@
*/ */
package org.hibernate.persister.entity; 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.AssertionFailure;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
@ -34,7 +43,6 @@ import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
import org.hibernate.sql.CaseFragment; import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.InFragment; import org.hibernate.sql.InFragment;
import org.hibernate.sql.Insert; import org.hibernate.sql.Insert;
@ -46,15 +54,6 @@ import org.hibernate.type.Type;
import org.jboss.logging.Logger; 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 <tt>EntityPersister</tt> implementing the normalized "table-per-subclass" * An <tt>EntityPersister</tt> implementing the normalized "table-per-subclass"
* mapping strategy * mapping strategy

View File

@ -42,7 +42,7 @@ import org.hibernate.mapping.Value;
import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.query.ComparisonOperator; import org.hibernate.query.ComparisonOperator;
import org.hibernate.query.NavigablePath; 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.InFragment;
import org.hibernate.sql.Insert; import org.hibernate.sql.Insert;
import org.hibernate.sql.SelectFragment; import org.hibernate.sql.SelectFragment;

View File

@ -45,12 +45,13 @@ import org.hibernate.metamodel.mapping.StateArrayContributorMapping;
import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
import org.hibernate.sql.SelectFragment; import org.hibernate.sql.SelectFragment;
import org.hibernate.sql.SimpleSelect;
import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.JoinType;
import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBase;
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; 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.TableGroup;
import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.from.UnionTableGroup; import org.hibernate.sql.ast.tree.from.UnionTableGroup;

View File

@ -52,14 +52,13 @@ import org.hibernate.query.spi.AbstractQuery;
import org.hibernate.query.spi.MutableQueryOptions; import org.hibernate.query.spi.MutableQueryOptions;
import org.hibernate.query.spi.QueryParameterBindings; import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.spi.ScrollableResultsImplementor; import org.hibernate.query.spi.ScrollableResultsImplementor;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.result.NoMoreReturnsException; import org.hibernate.result.NoMoreReturnsException;
import org.hibernate.result.Output; import org.hibernate.result.Output;
import org.hibernate.result.ResultSetOutput; import org.hibernate.result.ResultSetOutput;
import org.hibernate.result.UpdateCountOutput; import org.hibernate.result.UpdateCountOutput;
import org.hibernate.result.spi.ResultContext; import org.hibernate.result.spi.ResultContext;
import org.hibernate.sql.exec.spi.DomainParameterBindingContext;
import org.hibernate.sql.results.NoMoreOutputsException; import org.hibernate.sql.results.NoMoreOutputsException;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -70,7 +69,7 @@ import org.jboss.logging.Logger;
*/ */
public class ProcedureCallImpl<R> public class ProcedureCallImpl<R>
extends AbstractQuery<R> extends AbstractQuery<R>
implements ProcedureCallImplementor<R>, ResultContext, DomainParameterBindingContext { implements ProcedureCallImplementor<R>, ResultContext {
private static final CoreMessageLogger LOG = Logger.getMessageLogger( private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class, CoreMessageLogger.class,
ProcedureCallImpl.class.getName() ProcedureCallImpl.class.getName()
@ -229,31 +228,15 @@ public class ProcedureCallImpl<R>
return this; return this;
} }
@Override
public DomainParameterBindingContext getDomainParameterBindingContext() {
return this;
}
@Override @Override
public QueryParameterBindings getParameterBindings() { public QueryParameterBindings getParameterBindings() {
return paramBindings; return paramBindings;
} }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// DomainParameterBindingContext
@Override
public SessionFactoryImplementor getSessionFactory() { public SessionFactoryImplementor getSessionFactory() {
return getSession().getFactory(); return getSession().getFactory();
} }
@Override
public <T> List<T> getLoadIdentifiers() {
return Collections.emptyList();
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Parameter registrations // Parameter registrations

View File

@ -15,14 +15,14 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl; import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl;
import org.hibernate.query.named.AbstractNamedQueryMemento; import org.hibernate.query.named.AbstractNamedQueryMemento;
import org.hibernate.query.named.NameableQuery; import org.hibernate.query.named.NameableQuery;
import org.hibernate.query.named.NamedQueryMemento; import org.hibernate.query.named.NamedQueryProducer;
/** /**
* NamedQueryMemento for HQL queries * NamedQueryMemento for HQL queries
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface NamedHqlQueryMemento extends NamedQueryMemento { public interface NamedHqlQueryMemento extends NamedQueryProducer {
/** /**
* Informational access to the HQL query string * Informational access to the HQL query string
*/ */

View File

@ -12,6 +12,7 @@ import org.hibernate.CacheMode;
import org.hibernate.FlushMode; import org.hibernate.FlushMode;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.spi.QueryParameterImplementor; import org.hibernate.query.spi.QueryParameterImplementor;
/** /**

View File

@ -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);
<T> QueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> javaType);
}

View File

@ -107,7 +107,7 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
} }
@Override @Override
public <T> NativeQueryImplementor<T> toQuery(SharedSessionContractImplementor session) { public NativeQueryImplementor toQuery(SharedSessionContractImplementor session) {
//noinspection unchecked //noinspection unchecked
return toQuery( session, (Class) null ); return toQuery( session, (Class) null );
} }

View File

@ -15,7 +15,6 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; 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.ParameterInterpretation;
import org.hibernate.query.sql.spi.SelectInterpretationsKey; import org.hibernate.query.sql.spi.SelectInterpretationsKey;
import org.hibernate.sql.exec.spi.Callback; 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.exec.spi.ExecutionContext;
import org.hibernate.sql.results.spi.JdbcValuesMappingProducer; import org.hibernate.sql.results.spi.JdbcValuesMappingProducer;
import org.hibernate.sql.results.spi.RowTransformer; import org.hibernate.sql.results.spi.RowTransformer;
@ -95,7 +93,7 @@ import static org.hibernate.jpa.QueryHints.HINT_NATIVE_LOCKMODE;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public class NativeQueryImpl<R> public class NativeQueryImpl<R>
extends AbstractQuery<R> extends AbstractQuery<R>
implements NativeQueryImplementor<R>, DomainParameterBindingContext, ExecutionContext { implements NativeQueryImplementor<R>, ExecutionContext {
private final String sqlString; private final String sqlString;
private final ParameterMetadataImplementor parameterMetadata; private final ParameterMetadataImplementor parameterMetadata;
@ -225,27 +223,15 @@ public class NativeQueryImpl<R>
return queryOptions; return queryOptions;
} }
@Override
public DomainParameterBindingContext getDomainParameterBindingContext() {
return this;
}
@Override @Override
public Callback getCallback() { public Callback getCallback() {
throw new NotYetImplementedFor6Exception(); throw new NotYetImplementedFor6Exception();
} }
@Override
public SessionFactoryImplementor getSessionFactory() { public SessionFactoryImplementor getSessionFactory() {
return getSession().getFactory(); return getSession().getFactory();
} }
@Override
public <T> List<T> getLoadIdentifiers() {
//noinspection unchecked
return (List) Collections.singletonList( collectionKey );
}
@Override @Override
public QueryParameterBindings getQueryParameterBindings() { public QueryParameterBindings getQueryParameterBindings() {
return parameterBindings; return parameterBindings;

View File

@ -14,6 +14,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.named.AbstractNamedQueryMemento; import org.hibernate.query.named.AbstractNamedQueryMemento;
import org.hibernate.query.named.NamedQueryMemento; import org.hibernate.query.named.NamedQueryMemento;
import org.hibernate.query.named.NamedQueryProducer;
import org.hibernate.query.sql.internal.NamedNativeQueryMementoImpl; import org.hibernate.query.sql.internal.NamedNativeQueryMementoImpl;
/** /**
@ -21,7 +22,7 @@ import org.hibernate.query.sql.internal.NamedNativeQueryMementoImpl;
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface NamedNativeQueryMemento extends NamedQueryMemento { public interface NamedNativeQueryMemento extends NamedQueryProducer {
/** /**
* Informational access to the SQL query string * Informational access to the SQL query string
*/ */
@ -35,7 +36,7 @@ public interface NamedNativeQueryMemento extends NamedQueryMemento {
/** /**
* Convert the memento into an untyped executable query * Convert the memento into an untyped executable query
*/ */
<T> NativeQueryImplementor<T> toQuery(SharedSessionContractImplementor session); NativeQueryImplementor toQuery(SharedSessionContractImplementor session);
/** /**
* Convert the memento into a typed executable query * Convert the memento into a typed executable query

View File

@ -167,7 +167,7 @@ public class ConcreteSqmSelectQueryPlan<R> implements SelectQueryPlan<R> {
final SqmSelectToSqlAstConverter sqmConverter = sqmTranslatorFactory.createSelectConverter( final SqmSelectToSqlAstConverter sqmConverter = sqmTranslatorFactory.createSelectConverter(
executionContext.getQueryOptions(), executionContext.getQueryOptions(),
domainParameterXref, domainParameterXref,
executionContext.getDomainParameterBindingContext().getQueryParameterBindings(), executionContext.getQueryParameterBindings(),
executionContext.getLoadQueryInfluencers(), executionContext.getLoadQueryInfluencers(),
sessionFactory sessionFactory
); );
@ -189,7 +189,7 @@ public class ConcreteSqmSelectQueryPlan<R> implements SelectQueryPlan<R> {
final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings( final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(
executionContext.getDomainParameterBindingContext().getQueryParameterBindings(), executionContext.getQueryParameterBindings(),
domainParameterXref, domainParameterXref,
jdbcParamsXref, jdbcParamsXref,
// todo (6.0) : ugh. this one is important // todo (6.0) : ugh. this one is important

View File

@ -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.select.SqmSelection;
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement; import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
import org.hibernate.sql.exec.spi.Callback; 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.exec.spi.ExecutionContext;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
@ -67,7 +66,7 @@ import org.hibernate.type.BasicType;
*/ */
public class QuerySqmImpl<R> public class QuerySqmImpl<R>
extends AbstractQuery<R> extends AbstractQuery<R>
implements HqlQueryImplementor<R>, ExecutionContext, DomainParameterBindingContext { implements HqlQueryImplementor<R>, ExecutionContext {
private final String hqlString; private final String hqlString;
private final SqmStatement sqmStatement; private final SqmStatement sqmStatement;
@ -269,7 +268,6 @@ public class QuerySqmImpl<R>
} }
} }
@Override
public SessionFactoryImplementor getSessionFactory() { public SessionFactoryImplementor getSessionFactory() {
return getSession().getFactory(); return getSession().getFactory();
} }
@ -567,20 +565,11 @@ public class QuerySqmImpl<R>
return new UpdateQueryPlanImpl( sqmStatement, updateHandler, this ); return new UpdateQueryPlanImpl( sqmStatement, updateHandler, this );
} }
@Override
public DomainParameterBindingContext getDomainParameterBindingContext() {
return this;
}
@Override @Override
public Callback getCallback() { public Callback getCallback() {
return afterLoadAction -> {}; return afterLoadAction -> {};
} }
@Override
public <T> List<T> getLoadIdentifiers() {
return null;
}
@Override @Override
public NamedHqlQueryMemento toMemento(String name) { public NamedHqlQueryMemento toMemento(String name) {

View File

@ -27,7 +27,7 @@ import org.hibernate.metamodel.spi.DomainMetamodel;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.sqm.SqmExpressable; import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.SqmPathSource; 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.sql.SqmToSqlAstConverter;
import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPath;

View File

@ -26,7 +26,7 @@ import org.hibernate.query.spi.QueryParameterBinding;
import org.hibernate.query.spi.QueryParameterBindings; import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.spi.QueryParameterImplementor; import org.hibernate.query.spi.QueryParameterImplementor;
import org.hibernate.query.sqm.spi.JdbcParameterBySqmParameterAccess; 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.SqmDmlStatement;
import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.query.sqm.tree.SqmStatement;
import org.hibernate.query.sqm.tree.expression.SqmParameter; import org.hibernate.query.sqm.tree.expression.SqmParameter;
@ -155,7 +155,9 @@ public class SqmUtil {
Map<QueryParameterImplementor<?>, Map<SqmParameter, List<JdbcParameter>>> jdbcParamXref, Map<QueryParameterImplementor<?>, Map<SqmParameter, List<JdbcParameter>>> jdbcParamXref,
SqlAstCreationState sqlAstCreationState, SqlAstCreationState sqlAstCreationState,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( domainParameterXref ); final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl(
domainParameterXref.getSqmParameterCount()
);
for ( Map.Entry<QueryParameterImplementor<?>, List<SqmParameter>> entry : for ( Map.Entry<QueryParameterImplementor<?>, List<SqmParameter>> entry :
domainParameterXref.getSqmParamByQueryParam().entrySet() ) { domainParameterXref.getSqmParamByQueryParam().entrySet() ) {

View File

@ -96,8 +96,12 @@ import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.JoinType; import org.hibernate.sql.ast.JoinType;
import org.hibernate.sql.ast.spi.FromClauseAccess; import org.hibernate.sql.ast.spi.FromClauseAccess;
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; 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.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.SqlAstTreeHelper;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression; import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression; import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression; import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
@ -218,16 +222,6 @@ public abstract class BaseSqmToSqlAstConverter
return sqlAliasBaseManager; return sqlAliasBaseManager;
} }
@Override
public DomainParameterXref getDomainParameterXref() {
return domainParameterXref;
}
@Override
public QueryParameterBindings getDomainParameterBindings() {
return domainParameterBindings;
}
@Override @Override
public LockMode determineLockMode(String identificationVariable) { public LockMode determineLockMode(String identificationVariable) {
return queryOptions.getLockOptions().getEffectiveLockMode( identificationVariable ); return queryOptions.getLockOptions().getEffectiveLockMode( identificationVariable );
@ -287,8 +281,7 @@ public abstract class BaseSqmToSqlAstConverter
sqlQuerySpec, sqlQuerySpec,
processingStateStack.getCurrent(), processingStateStack.getCurrent(),
this, this,
currentClauseStack::getCurrent, currentClauseStack::getCurrent
() -> (expression) -> {}
) )
); );
@ -742,7 +735,13 @@ public abstract class BaseSqmToSqlAstConverter
this.jdbcParameters.addParameters( jdbcParametersForSqm ); this.jdbcParameters.addParameters( jdbcParametersForSqm );
this.jdbcParamsBySqmParam.put( sqmParameter, 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) { protected MappingModelExpressable<?> determineValueMapping(SqmExpression<?> sqmExpression) {

View File

@ -8,7 +8,7 @@ package org.hibernate.query.sqm.sql;
import org.hibernate.internal.util.collections.Stack; import org.hibernate.internal.util.collections.Stack;
import org.hibernate.query.sqm.SemanticQueryWalker; 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; import org.hibernate.sql.ast.Clause;
/** /**

View File

@ -12,8 +12,8 @@ import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.mapping.BasicValuedModelPart; import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.sql.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.query.sqm.sql.SqlExpressionResolver; import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;

View File

@ -14,9 +14,9 @@ import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.hibernate.query.sqm.sql.ConversionException; import org.hibernate.query.sqm.sql.ConversionException;
import org.hibernate.query.sqm.sql.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.query.sqm.sql.SqlAstProcessingState; import org.hibernate.sql.ast.spi.SqlAstProcessingState;
import org.hibernate.query.sqm.sql.SqlExpressionResolver; import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Expression;
@ -34,19 +34,16 @@ public class SqlAstProcessingStateImpl implements SqlAstProcessingState, SqlExpr
private final SqlAstProcessingState parentState; private final SqlAstProcessingState parentState;
private final SqlAstCreationState creationState; private final SqlAstCreationState creationState;
private final Supplier<Clause> currentClauseAccess; private final Supplier<Clause> currentClauseAccess;
private final Supplier<Consumer<Expression>> resolvedExpressionConsumerAccess;
private final Map<String,Expression> expressionMap = new HashMap<>(); private final Map<String,Expression> expressionMap = new HashMap<>();
public SqlAstProcessingStateImpl( public SqlAstProcessingStateImpl(
SqlAstProcessingState parentState, SqlAstProcessingState parentState,
SqlAstCreationState creationState, SqlAstCreationState creationState,
Supplier<Clause> currentClauseAccess, Supplier<Clause> currentClauseAccess) {
Supplier<Consumer<Expression>> resolvedExpressionConsumerAccess) {
this.parentState = parentState; this.parentState = parentState;
this.creationState = creationState; this.creationState = creationState;
this.currentClauseAccess = currentClauseAccess; this.currentClauseAccess = currentClauseAccess;
this.resolvedExpressionConsumerAccess = resolvedExpressionConsumerAccess;
} }
@ -93,8 +90,6 @@ public class SqlAstProcessingStateImpl implements SqlAstProcessingState, SqlExpr
final Expression result = normalize( expression ); final Expression result = normalize( expression );
resolvedExpressionConsumerAccess.get().accept( result );
return result; return result;
} }

View File

@ -12,9 +12,9 @@ import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.hibernate.metamodel.mapping.MappingModelExpressable; import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.query.sqm.sql.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.query.sqm.sql.SqlAstProcessingState; import org.hibernate.sql.ast.spi.SqlAstProcessingState;
import org.hibernate.query.sqm.sql.SqlAstQuerySpecProcessingState; import org.hibernate.sql.ast.spi.SqlAstQuerySpecProcessingState;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlAstWalker; import org.hibernate.sql.ast.spi.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.spi.SqlSelection;
@ -37,9 +37,8 @@ public class SqlAstQuerySpecProcessingStateImpl
QuerySpec querySpec, QuerySpec querySpec,
SqlAstProcessingState parent, SqlAstProcessingState parent,
SqlAstCreationState creationState, SqlAstCreationState creationState,
Supplier<Clause> currentClauseAccess, Supplier<Clause> currentClauseAccess) {
Supplier<Consumer<Expression>> resolvedExpressionConsumerAccess) { super( parent, creationState, currentClauseAccess );
super( parent, creationState, currentClauseAccess, resolvedExpressionConsumerAccess );
this.querySpec = querySpec; this.querySpec = querySpec;
} }

View File

@ -7,6 +7,7 @@
package org.hibernate.query.sqm.sql.internal; package org.hibernate.query.sqm.sql.internal;
import java.util.List; import java.util.List;
import java.util.function.Function;
import org.hibernate.metamodel.mapping.MappingModelExpressable; import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.metamodel.model.domain.AllowableParameterType; import org.hibernate.metamodel.model.domain.AllowableParameterType;
@ -28,16 +29,22 @@ import org.hibernate.sql.results.spi.DomainResultCreationState;
*/ */
public class SqmParameterInterpretation implements Expression, DomainResultProducer { public class SqmParameterInterpretation implements Expression, DomainResultProducer {
private final SqmParameter sqmParameter; private final SqmParameter sqmParameter;
private final QueryParameterImplementor<?> queryParameter;
private final MappingModelExpressable valueMapping; private final MappingModelExpressable valueMapping;
private final Function<QueryParameterImplementor, QueryParameterBinding> queryParameterBindingResolver;
private final Expression resolvedExpression; private final Expression resolvedExpression;
public SqmParameterInterpretation( public SqmParameterInterpretation(
SqmParameter sqmParameter, SqmParameter sqmParameter,
QueryParameterImplementor<?> queryParameter,
List<JdbcParameter> jdbcParameters, List<JdbcParameter> jdbcParameters,
MappingModelExpressable valueMapping) { MappingModelExpressable valueMapping,
Function<QueryParameterImplementor, QueryParameterBinding> queryParameterBindingResolver) {
this.sqmParameter = sqmParameter; this.sqmParameter = sqmParameter;
this.queryParameter = queryParameter;
this.valueMapping = valueMapping; this.valueMapping = valueMapping;
this.queryParameterBindingResolver = queryParameterBindingResolver;
assert jdbcParameters != null; assert jdbcParameters != null;
assert jdbcParameters.size() > 0; assert jdbcParameters.size() > 0;
@ -67,12 +74,7 @@ public class SqmParameterInterpretation implements Expression, DomainResultProdu
AllowableParameterType nodeType = sqmParameter.getNodeType(); AllowableParameterType nodeType = sqmParameter.getNodeType();
if ( nodeType == null ) { if ( nodeType == null ) {
final QueryParameterImplementor<?> queryParameter = creationState.getSqlAstCreationState() final QueryParameterBinding<?> binding = queryParameterBindingResolver.apply( queryParameter );
.getDomainParameterXref()
.getQueryParameter( sqmParameter );
final QueryParameterBinding<?> binding = creationState.getSqlAstCreationState()
.getDomainParameterBindings()
.getBinding( queryParameter );
nodeType = binding.getBindType(); nodeType = binding.getBindType();
} }

View File

@ -12,7 +12,7 @@ import java.util.List;
import org.hibernate.metamodel.mapping.MappingModelExpressable; import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.internal.SqmMappingModelHelper; 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.SqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmTuple; import org.hibernate.query.sqm.tree.expression.SqmTuple;
import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Expression;

View File

@ -30,7 +30,7 @@ import org.hibernate.query.spi.QueryOptions;
import org.hibernate.query.spi.QueryParameterBindings; import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.sqm.internal.DomainParameterXref; import org.hibernate.query.sqm.internal.DomainParameterXref;
import org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter; 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.sql.SqmSelectToSqlAstConverter;
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType; import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;

View File

@ -10,7 +10,6 @@ import java.util.Set;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.spi.QueryOptions; import org.hibernate.query.spi.QueryOptions;
import org.hibernate.sql.exec.spi.DomainParameterBindingContext;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -21,6 +20,4 @@ public interface ResultContext {
Set<String> getSynchronizedQuerySpaces(); Set<String> getSynchronizedQuerySpaces();
QueryOptions getQueryOptions(); QueryOptions getQueryOptions();
DomainParameterBindingContext getDomainParameterBindingContext();
} }

View File

@ -21,7 +21,7 @@ public class AbstractSqlAstToJdbcOperationConverter
extends AbstractSqlAstWalker extends AbstractSqlAstWalker
implements SqlAstToJdbcOperationConverter { implements SqlAstToJdbcOperationConverter {
private final Set<String> affectedTableNames = new HashSet<>(); private final Set<String> affectedTableExpressions = new HashSet<>();
protected AbstractSqlAstToJdbcOperationConverter(SessionFactoryImplementor sessionFactory) { protected AbstractSqlAstToJdbcOperationConverter(SessionFactoryImplementor sessionFactory) {
super( sessionFactory ); super( sessionFactory );
@ -33,16 +33,21 @@ public class AbstractSqlAstToJdbcOperationConverter
} }
@Override @Override
public Set<String> getAffectedTableNames() { public Set<String> getAffectedTableExpressions() {
return affectedTableNames; return affectedTableExpressions;
} }
@Override
protected void renderTableReference(TableReference tableReference) {
super.renderTableReference( tableReference );
registerAffectedTable( tableReference );
}
protected void registerAffectedTable(TableReference tableReference) { protected void registerAffectedTable(TableReference tableReference) {
registerAffectedTable( tableReference.getTableExpression() ); registerAffectedTable( tableReference.getTableExpression() );
} }
protected void registerAffectedTable(String tableExpression) { protected void registerAffectedTable(String tableExpression) {
affectedTableNames.add( tableExpression ); affectedTableExpressions.add( tableExpression );
} }
} }

View File

@ -4,14 +4,12 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * 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 * 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.HashMap;
import java.util.Map; import java.util.Map;
import org.hibernate.sql.ast.SqlTreeCreationLogger; 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 * Helper used in creating unique SQL table aliases for a SQL AST

View File

@ -4,16 +4,11 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * 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 * 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 java.util.List;
import org.hibernate.LockMode; 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.Fetch;
import org.hibernate.sql.results.spi.FetchParent; import org.hibernate.sql.results.spi.FetchParent;
@ -34,10 +29,6 @@ public interface SqlAstCreationState {
SqlAliasBaseGenerator getSqlAliasBaseGenerator(); SqlAliasBaseGenerator getSqlAliasBaseGenerator();
DomainParameterXref getDomainParameterXref();
QueryParameterBindings getDomainParameterBindings();
LockMode determineLockMode(String identificationVariable); LockMode determineLockMode(String identificationVariable);
/** /**

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * 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 * 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 * Generalized access to state information relative to the "current process" of

View File

@ -4,11 +4,12 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * 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 * 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; import org.hibernate.sql.ast.tree.select.QuerySpec;
/** /**
* SqlAstProcessingState specialization for
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface SqlAstQuerySpecProcessingState extends SqlAstProcessingState { public interface SqlAstQuerySpecProcessingState extends SqlAstProcessingState {

View File

@ -18,5 +18,5 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface SqlAstToJdbcOperationConverter extends SqlAstWalker, SqlTypeDescriptorIndicators { public interface SqlAstToJdbcOperationConverter extends SqlAstWalker, SqlTypeDescriptorIndicators {
Set<String> getAffectedTableNames(); Set<String> getAffectedTableExpressions();
} }

View File

@ -4,11 +4,10 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * 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 * 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 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.expression.Expression;
import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;

View File

@ -44,7 +44,7 @@ public class StandardSqlAstSelectTranslator
querySpec.getSelectClause().getSqlSelections(), querySpec.getSelectClause().getSqlSelections(),
Collections.emptyList() Collections.emptyList()
), ),
getAffectedTableNames() getAffectedTableExpressions()
); );
} }
@ -63,7 +63,7 @@ public class StandardSqlAstSelectTranslator
sqlAstSelect.getQuerySpec().getSelectClause().getSqlSelections(), sqlAstSelect.getQuerySpec().getSelectClause().getSqlSelections(),
sqlAstSelect.getDomainResultDescriptors() sqlAstSelect.getDomainResultDescriptors()
), ),
sqlAstSelect.getAffectedTableExpressions() getAffectedTableExpressions()
); );
} }

View File

@ -12,7 +12,7 @@ import java.util.function.Consumer;
import org.hibernate.metamodel.mapping.BasicValuedMapping; import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.JdbcMapping; 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.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.spi.SqlSelection;

View File

@ -15,6 +15,7 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressable; import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.sql.ast.spi.SqlAstWalker; import org.hibernate.sql.ast.spi.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlSelection; 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.sql.results.internal.SqlSelectionImpl;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
@ -50,6 +51,14 @@ public class ColumnReference implements Expression {
this.jdbcMapping = jdbcMapping; this.jdbcMapping = jdbcMapping;
} }
public ColumnReference(
TableReference tableReference,
String columnExpression,
JdbcMapping jdbcMapping,
SessionFactoryImplementor sessionFactory) {
this( tableReference.getIdentificationVariable(), columnExpression, jdbcMapping, sessionFactory );
}
public String getExpressionText() { public String getExpressionText() {
return referenceExpression; return referenceExpression;
} }
@ -58,6 +67,10 @@ public class ColumnReference implements Expression {
return getExpressionText(); return getExpressionText();
} }
public JdbcMapping getJdbcMapping() {
return jdbcMapping;
}
@Override @Override
public MappingModelExpressable getExpressionType() { public MappingModelExpressable getExpressionType() {
return (MappingModelExpressable) jdbcMapping; return (MappingModelExpressable) jdbcMapping;

View File

@ -12,7 +12,7 @@ import java.util.function.Supplier;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.ModelPartContainer; import org.hibernate.metamodel.mapping.ModelPartContainer;
import org.hibernate.query.NavigablePath; 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.JoinType;
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;

View File

@ -8,7 +8,7 @@ package org.hibernate.sql.ast.tree.from;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.query.NavigablePath; 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.JoinType;
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;

View File

@ -7,7 +7,7 @@
package org.hibernate.sql.ast.tree.from; package org.hibernate.sql.ast.tree.from;
import org.hibernate.metamodel.mapping.ModelPartContainer; 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 * Marker interface for anything which produces a TableGroup

View File

@ -6,7 +6,7 @@
*/ */
package org.hibernate.sql.ast.tree.from; 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.JoinType;
import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBase;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;

View File

@ -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
);
}
}

View File

@ -25,9 +25,9 @@ import org.hibernate.sql.exec.spi.JdbcParameterBindings;
public class JdbcParameterBindingsImpl implements JdbcParameterBindings { public class JdbcParameterBindingsImpl implements JdbcParameterBindings {
private Map<JdbcParameter, JdbcParameterBinding> bindingMap; private Map<JdbcParameter, JdbcParameterBinding> bindingMap;
public JdbcParameterBindingsImpl(DomainParameterXref domainParameterXref) { public JdbcParameterBindingsImpl(int expectedParameterCount) {
if ( domainParameterXref.getSqmParameterCount() > 0 ) { if ( expectedParameterCount > 0 ) {
bindingMap = new IdentityHashMap<>( domainParameterXref.getSqmParameterCount() ); bindingMap = new IdentityHashMap<>( expectedParameterCount );
} }
} }

View File

@ -218,7 +218,7 @@ public class JdbcSelectExecutorStandardImpl implements JdbcSelectExecutor {
final List<Object[]> cachedResults; final List<Object[]> cachedResults;
final boolean queryCacheEnabled = executionContext.getSession().getFactory().getSessionFactoryOptions().isQueryCacheEnabled(); final boolean queryCacheEnabled = executionContext.getSession().getFactory().getSessionFactoryOptions().isQueryCacheEnabled();
final CacheMode cacheMode = resolveCacheMode( executionContext ); final CacheMode cacheMode = JdbcExecHelper.resolveCacheMode( executionContext );
final JdbcValuesMapping jdbcValuesMapping = jdbcSelect.getJdbcValuesMappingProducer() final JdbcValuesMapping jdbcValuesMapping = jdbcSelect.getJdbcValuesMappingProducer()
.resolve( resultSetAccess, executionContext.getSession().getFactory() ); .resolve( resultSetAccess, executionContext.getSession().getFactory() );
@ -241,7 +241,7 @@ public class JdbcSelectExecutorStandardImpl implements JdbcSelectExecutor {
queryResultsCacheKey = QueryKey.from( queryResultsCacheKey = QueryKey.from(
jdbcSelect.getSql(), jdbcSelect.getSql(),
executionContext.getQueryOptions().getLimit(), executionContext.getQueryOptions().getLimit(),
executionContext.getDomainParameterBindingContext().getQueryParameterBindings(), executionContext.getQueryParameterBindings(),
executionContext.getSession() 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;
}
} }

View File

@ -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();
<T> List<T> getLoadIdentifiers();
QueryParameterBindings getQueryParameterBindings();
}

View File

@ -11,6 +11,7 @@ import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.spi.QueryOptions; import org.hibernate.query.spi.QueryOptions;
import org.hibernate.query.spi.QueryParameterBindings;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -32,7 +33,7 @@ public interface ExecutionContext {
return getSession().getLoadQueryInfluencers(); return getSession().getLoadQueryInfluencers();
} }
DomainParameterBindingContext getDomainParameterBindingContext(); QueryParameterBindings getQueryParameterBindings();
Callback getCallback(); Callback getCallback();

View File

@ -73,12 +73,14 @@ public class DeferredResultSetAccess extends AbstractResultSetAccess {
preparedStatement = statementCreator.apply( sql ); preparedStatement = statementCreator.apply( sql );
// set options // set options
if ( executionContext.getQueryOptions() != null ) {
if ( executionContext.getQueryOptions().getFetchSize() != null ) { if ( executionContext.getQueryOptions().getFetchSize() != null ) {
preparedStatement.setFetchSize( executionContext.getQueryOptions().getFetchSize() ); preparedStatement.setFetchSize( executionContext.getQueryOptions().getFetchSize() );
} }
if ( executionContext.getQueryOptions().getTimeout() != null ) { if ( executionContext.getQueryOptions().getTimeout() != null ) {
preparedStatement.setQueryTimeout( executionContext.getQueryOptions().getTimeout() ); preparedStatement.setQueryTimeout( executionContext.getQueryOptions().getTimeout() );
} }
}
// todo : limit/offset // todo : limit/offset

View File

@ -15,6 +15,7 @@ import org.hibernate.query.Limit;
import org.hibernate.query.spi.QueryOptions; import org.hibernate.query.spi.QueryOptions;
import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.exec.ExecutionException; import org.hibernate.sql.exec.ExecutionException;
import org.hibernate.sql.exec.internal.JdbcExecHelper;
import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.results.internal.caching.QueryCachePutManager; import org.hibernate.sql.results.internal.caching.QueryCachePutManager;
import org.hibernate.sql.results.internal.caching.QueryCachePutManagerDisabledImpl; import org.hibernate.sql.results.internal.caching.QueryCachePutManagerDisabledImpl;
@ -64,7 +65,7 @@ public class JdbcValuesResultSetImpl extends AbstractJdbcValues {
} }
private static int interpretNumberOfRowsToProcess(QueryOptions queryOptions) { private static int interpretNumberOfRowsToProcess(QueryOptions queryOptions) {
if ( queryOptions.getLimit() == null ) { if ( queryOptions == null || queryOptions.getLimit() == null ) {
return -1; return -1;
} }
final Limit limit = queryOptions.getLimit(); final Limit limit = queryOptions.getLimit();
@ -83,7 +84,7 @@ public class JdbcValuesResultSetImpl extends AbstractJdbcValues {
.getFactory() .getFactory()
.getSessionFactoryOptions() .getSessionFactoryOptions()
.isQueryCacheEnabled(); .isQueryCacheEnabled();
final CacheMode cacheMode = queryOptions.getCacheMode(); final CacheMode cacheMode = JdbcExecHelper.resolveCacheMode( executionContext );
if ( queryCacheEnabled && cacheMode.isPutEnabled() ) { if ( queryCacheEnabled && cacheMode.isPutEnabled() ) {
final QueryResultsCache queryCache = executionContext.getSession().getFactory() final QueryResultsCache queryCache = executionContext.getSession().getFactory()

View File

@ -9,13 +9,12 @@ package org.hibernate.sql.results.internal;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.loader.plan.spi.EntityFetch; import org.hibernate.loader.plan.spi.EntityFetch;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.spi.QueryOptions; 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.Callback;
import org.hibernate.sql.exec.spi.DomainParameterBindingContext;
import org.hibernate.sql.results.spi.Initializer; import org.hibernate.sql.results.spi.Initializer;
import org.hibernate.sql.results.spi.JdbcValues; import org.hibernate.sql.results.spi.JdbcValues;
import org.hibernate.sql.results.spi.JdbcValuesSourceProcessingState; import org.hibernate.sql.results.spi.JdbcValuesSourceProcessingState;
@ -99,8 +98,8 @@ public class RowProcessingStateStandardImpl implements RowProcessingState {
} }
@Override @Override
public DomainParameterBindingContext getDomainParameterBindingContext() { public QueryParameterBindings getQueryParameterBindings() {
throw new NotYetImplementedFor6Exception(); return getJdbcValuesSourceProcessingState().getExecutionContext().getQueryParameterBindings();
} }
@Override @Override

View File

@ -86,6 +86,11 @@ public class RootBiDirectionalFetchImpl implements BiDirectionalFetch, Fetchable
return null; return null;
} }
@Override
public String getPartName() {
return navigablePath.getLocalName();
}
@Override @Override
public JavaTypeDescriptor getJavaTypeDescriptor() { public JavaTypeDescriptor getJavaTypeDescriptor() {
return referencedRoot.getResultJavaTypeDescriptor(); return referencedRoot.getResultJavaTypeDescriptor();

View File

@ -9,8 +9,8 @@ package org.hibernate.sql.results.spi;
import java.util.List; import java.util.List;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.query.sqm.sql.SqlAliasBaseManager; import org.hibernate.sql.ast.spi.SqlAliasBaseManager;
import org.hibernate.query.sqm.sql.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
/** /**
* @author Steve Ebersole * @author Steve Ebersole

View File

@ -59,7 +59,7 @@ import org.hibernate.persister.spi.PersisterClassResolver;
import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; 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.JoinType;
import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBase;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;

View File

@ -7,14 +7,10 @@
package org.hibernate.orm.test.loading; package org.hibernate.orm.test.loading;
import org.hibernate.Hibernate; 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.StandardDomainModel;
import org.hibernate.testing.orm.domain.gambit.BasicEntity; import org.hibernate.testing.orm.domain.gambit.BasicEntity;
import org.hibernate.testing.orm.junit.DomainModel; 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.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryFunctionalTesting; import org.hibernate.testing.orm.junit.SessionFactoryFunctionalTesting;
import org.hibernate.testing.orm.junit.SessionFactoryScope; 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.Tags;
import org.junit.jupiter.api.Test; 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.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat; 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 * @author Steve Ebersole
@ -50,19 +43,20 @@ public class LoadingSmokeTests {
session -> { session -> {
final BasicEntity loaded = session.byId( BasicEntity.class ).getReference( 1 ); final BasicEntity loaded = session.byId( BasicEntity.class ).getReference( 1 );
assertThat( loaded, notNullValue() ); assertThat( loaded, notNullValue() );
assertFalse( Hibernate.isInitialized( loaded ) ); assertThat( Hibernate.isInitialized( loaded ), is( false ) );
} }
); );
} }
@Test @Test
@FailureExpected( reason = "read-by-position not yet implemented for loading" )
public void testBasicGet(SessionFactoryScope scope) { public void testBasicGet(SessionFactoryScope scope) {
scope.inTransaction( scope.inTransaction(
session -> { session -> {
final BasicEntity gotten = session.byId( BasicEntity.class ).load( 1 ); final BasicEntity gotten = session.byId( BasicEntity.class ).load( 1 );
assertThat( gotten, notNullValue() ); assertThat( gotten, notNullValue() );
assertTrue( Hibernate.isInitialized( gotten ) ); assertThat( Hibernate.isInitialized( gotten ), is( true ) );
assertThat( gotten.getId(), is( 1 ) );
assertThat( gotten.getData(), is( "first" ) );
} }
); );
} }

View File

@ -18,8 +18,6 @@ import javax.persistence.Temporal;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
import org.hibernate.Session; 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.orm.test.query.sqm.BaseSqmUnitTest;
import org.hibernate.query.Query; import org.hibernate.query.Query;
import org.hibernate.query.SemanticException; 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.spi.QueryParameterBindings;
import org.hibernate.query.sqm.tree.expression.SqmParameter; import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement; 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.ExpectedException;
import org.hibernate.testing.orm.junit.ExpectedExceptionExtension; 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 org.junit.jupiter.api.extension.ExtendWith;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hibernate.testing.hamcrest.CollectionMatchers.hasSize; 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( "start", Instant.now().minus( 7, ChronoUnit.DAYS ), TemporalType.TIMESTAMP );
query.setParameter( "end", Instant.now().plus( 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" ); final QueryParameterBinding<?> startBinding = bindings.getBinding( "start" );
assertThat( startBinding.getExplicitTemporalPrecision(), equalTo( TemporalType.TIMESTAMP ) ); 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( "start", Instant.now().minus( 7, ChronoUnit.DAYS ), TemporalType.DATE );
query.setParameter( "end", Instant.now().plus( 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" ); final QueryParameterBinding<?> startBinding = bindings.getBinding( "start" );
assertThat( startBinding.getExplicitTemporalPrecision(), equalTo( TemporalType.DATE ) ); assertThat( startBinding.getExplicitTemporalPrecision(), equalTo( TemporalType.DATE ) );

View File

@ -59,7 +59,7 @@ import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.CollectionElementDefinition; import org.hibernate.persister.walking.spi.CollectionElementDefinition;
import org.hibernate.persister.walking.spi.CollectionIndexDefinition; import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; 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.JoinType;
import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBase;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;

View File

@ -60,7 +60,7 @@ import org.hibernate.persister.entity.MultiLoadOptions;
import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; 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.JoinType;
import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBase;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;