use of org.hibernate.sql.ast.tree.select.SelectStatement in project hibernate-orm by hibernate.
the class AbstractCteMutationHandler method execute.
@Override
public int execute(DomainQueryExecutionContext executionContext) {
final SqmDeleteOrUpdateStatement sqmMutationStatement = getSqmDeleteOrUpdateStatement();
final SessionFactoryImplementor factory = executionContext.getSession().getFactory();
final EntityMappingType entityDescriptor = getEntityDescriptor();
final String explicitDmlTargetAlias;
// We need an alias because we try to acquire a WRITE lock for these rows in the CTE
if (sqmMutationStatement.getTarget().getExplicitAlias() == null) {
explicitDmlTargetAlias = "dml_target";
} else {
explicitDmlTargetAlias = sqmMutationStatement.getTarget().getExplicitAlias();
}
final MultiTableSqmMutationConverter sqmConverter = new MultiTableSqmMutationConverter(entityDescriptor, sqmMutationStatement, sqmMutationStatement.getTarget(), explicitDmlTargetAlias, domainParameterXref, executionContext.getQueryOptions(), executionContext.getSession().getLoadQueryInfluencers(), executionContext.getQueryParameterBindings(), factory);
final Map<SqmParameter, List<JdbcParameter>> parameterResolutions;
if (domainParameterXref.getSqmParameterCount() == 0) {
parameterResolutions = Collections.emptyMap();
} else {
parameterResolutions = new IdentityHashMap<>();
}
final Map<SqmParameter, MappingModelExpressible> paramTypeResolutions = new LinkedHashMap<>();
final Predicate restriction = sqmConverter.visitWhereClause(sqmMutationStatement.getWhereClause(), columnReference -> {
}, (sqmParam, mappingType, jdbcParameters) -> paramTypeResolutions.put(sqmParam, mappingType));
sqmConverter.pruneTableGroupJoins();
final CteStatement idSelectCte = new CteStatement(BaseSqmToSqlAstConverter.createCteTable(getCteTable(), factory), MatchingIdSelectionHelper.generateMatchingIdSelectStatement(entityDescriptor, sqmMutationStatement, false, restriction, sqmConverter, executionContext, factory), // The id-select cte will be reused multiple times
CteMaterialization.MATERIALIZED);
// Create the main query spec that will return the count of
final QuerySpec querySpec = new QuerySpec(true, 1);
final List<DomainResult<?>> domainResults = new ArrayList<>(1);
final SelectStatement statement = new SelectStatement(querySpec, domainResults);
final JdbcServices jdbcServices = factory.getJdbcServices();
final SqlAstTranslator<JdbcSelect> translator = jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory().buildSelectTranslator(factory, statement);
final Expression count = createCountStar(factory, sqmConverter);
domainResults.add(new BasicResult<>(0, null, ((SqlExpressible) count).getJdbcMapping().getJavaTypeDescriptor()));
querySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, count));
querySpec.getFromClause().addRoot(new CteTableGroup(new NamedTableReference(idSelectCte.getCteTable().getTableExpression(), CTE_TABLE_IDENTIFIER, false, factory)));
// Add all CTEs
statement.addCteStatement(idSelectCte);
addDmlCtes(statement, idSelectCte, sqmConverter, parameterResolutions, factory);
final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(executionContext.getQueryParameterBindings(), domainParameterXref, SqmUtil.generateJdbcParamsXref(domainParameterXref, sqmConverter), factory.getRuntimeMetamodels().getMappingMetamodel(), navigablePath -> sqmConverter.getMutatingTableGroup(), paramTypeResolutions::get, executionContext.getSession());
final LockOptions lockOptions = executionContext.getQueryOptions().getLockOptions();
final LockMode lockMode = lockOptions.getAliasSpecificLockMode(explicitDmlTargetAlias);
// Acquire a WRITE lock for the rows that are about to be modified
lockOptions.setAliasSpecificLockMode(explicitDmlTargetAlias, LockMode.WRITE);
final JdbcSelect select = translator.translate(jdbcParameterBindings, executionContext.getQueryOptions());
lockOptions.setAliasSpecificLockMode(explicitDmlTargetAlias, lockMode);
executionContext.getSession().autoFlushIfRequired(select.getAffectedTableNames());
List<Object> list = jdbcServices.getJdbcSelectExecutor().list(select, jdbcParameterBindings, SqmJdbcExecutionContextAdapter.omittingLockingAndPaging(executionContext), row -> row[0], ListResultsConsumer.UniqueSemantic.NONE);
return ((Number) list.get(0)).intValue();
}
use of org.hibernate.sql.ast.tree.select.SelectStatement in project hibernate-orm by hibernate.
the class CteDeleteHandler method addDmlCtes.
@Override
protected void addDmlCtes(CteContainer statement, CteStatement idSelectCte, MultiTableSqmMutationConverter sqmConverter, Map<SqmParameter, List<JdbcParameter>> parameterResolutions, SessionFactoryImplementor factory) {
final TableGroup updatingTableGroup = sqmConverter.getMutatingTableGroup();
final SelectStatement idSelectStatement = (SelectStatement) idSelectCte.getCteDefinition();
sqmConverter.getProcessingStateStack().push(new SqlAstQueryPartProcessingStateImpl(idSelectStatement.getQuerySpec(), sqmConverter.getCurrentProcessingState(), sqmConverter.getSqlAstCreationState(), sqmConverter.getCurrentClauseStack()::getCurrent, false));
getEntityDescriptor().visitSubTypeAttributeMappings(attribute -> {
if (attribute instanceof PluralAttributeMapping) {
final PluralAttributeMapping pluralAttribute = (PluralAttributeMapping) attribute;
if (pluralAttribute.getSeparateCollectionTable() != null) {
// Ensure that the FK target columns are available
final boolean useFkTarget = !(pluralAttribute.getKeyDescriptor().getTargetPart() instanceof EntityIdentifierMapping);
if (useFkTarget) {
final TableGroup mutatingTableGroup = sqmConverter.getMutatingTableGroup();
pluralAttribute.getKeyDescriptor().getTargetPart().applySqlSelections(mutatingTableGroup.getNavigablePath(), mutatingTableGroup, sqmConverter, (selection, jdbcMapping) -> {
idSelectStatement.getDomainResultDescriptors().add(new BasicResult<>(selection.getValuesArrayPosition(), null, jdbcMapping.getJavaTypeDescriptor()));
});
}
// this collection has a separate collection table, meaning it is one of:
// 1) element-collection
// 2) many-to-many
// 3) one-to many using a dedicated join-table
//
// in all of these cases, we should clean up the matching rows in the
// collection table
final String tableExpression = pluralAttribute.getSeparateCollectionTable();
final CteTable dmlResultCte = new CteTable(getCteTableName(pluralAttribute), idSelectCte.getCteTable().getCteColumns(), factory);
final NamedTableReference dmlTableReference = new NamedTableReference(tableExpression, DeleteStatement.DEFAULT_ALIAS, true, factory);
final List<ColumnReference> columnReferences = new ArrayList<>(idSelectCte.getCteTable().getCteColumns().size());
pluralAttribute.getKeyDescriptor().visitKeySelectables((index, selectable) -> columnReferences.add(new ColumnReference(dmlTableReference, selectable, factory)));
final MutationStatement dmlStatement = new DeleteStatement(dmlTableReference, createIdSubQueryPredicate(columnReferences, idSelectCte, useFkTarget ? pluralAttribute.getKeyDescriptor().getTargetPart() : null, factory), columnReferences);
statement.addCteStatement(new CteStatement(dmlResultCte, dmlStatement));
}
}
});
sqmConverter.getProcessingStateStack().pop();
getEntityDescriptor().visitConstraintOrderedTables((tableExpression, tableColumnsVisitationSupplier) -> {
final CteTable dmlResultCte = new CteTable(getCteTableName(tableExpression), idSelectCte.getCteTable().getCteColumns(), factory);
final TableReference updatingTableReference = updatingTableGroup.getTableReference(updatingTableGroup.getNavigablePath(), tableExpression, true, true);
final NamedTableReference dmlTableReference = resolveUnionTableReference(updatingTableReference, tableExpression);
final List<ColumnReference> columnReferences = new ArrayList<>(idSelectCte.getCteTable().getCteColumns().size());
tableColumnsVisitationSupplier.get().accept((index, selectable) -> columnReferences.add(new ColumnReference(dmlTableReference, selectable, factory)));
final MutationStatement dmlStatement = new DeleteStatement(dmlTableReference, createIdSubQueryPredicate(columnReferences, idSelectCte, factory), columnReferences);
statement.addCteStatement(new CteStatement(dmlResultCte, dmlStatement));
});
}
use of org.hibernate.sql.ast.tree.select.SelectStatement in project hibernate-orm by hibernate.
the class ConcreteSqmSelectQueryPlan method buildCacheableSqmInterpretation.
private static CacheableSqmInterpretation buildCacheableSqmInterpretation(SqmSelectStatement<?> sqm, DomainParameterXref domainParameterXref, DomainQueryExecutionContext executionContext) {
final SharedSessionContractImplementor session = executionContext.getSession();
final SessionFactoryImplementor sessionFactory = session.getFactory();
final QueryEngine queryEngine = sessionFactory.getQueryEngine();
final SqmTranslatorFactory sqmTranslatorFactory = queryEngine.getSqmTranslatorFactory();
final SqmTranslator<SelectStatement> sqmConverter = sqmTranslatorFactory.createSelectTranslator(sqm, executionContext.getQueryOptions(), domainParameterXref, executionContext.getQueryParameterBindings(), executionContext.getSession().getLoadQueryInfluencers(), sessionFactory, true);
// tableGroupAccess = sqmConverter.getFromClauseAccess();
final SqmTranslation<SelectStatement> sqmInterpretation = sqmConverter.translate();
final FromClauseAccess tableGroupAccess = sqmConverter.getFromClauseAccess();
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
final SqlAstTranslator<JdbcSelect> selectTranslator = sqlAstTranslatorFactory.buildSelectTranslator(sessionFactory, sqmInterpretation.getSqlAst());
final Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> jdbcParamsXref = SqmUtil.generateJdbcParamsXref(domainParameterXref, sqmInterpretation::getJdbcParamsBySqmParam);
final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(executionContext.getQueryParameterBindings(), domainParameterXref, jdbcParamsXref, session.getFactory().getRuntimeMetamodels().getMappingMetamodel(), tableGroupAccess::findTableGroup, new SqmParameterMappingModelResolutionAccess() {
@Override
@SuppressWarnings("unchecked")
public <T> MappingModelExpressible<T> getResolvedMappingModelType(SqmParameter<T> parameter) {
return (MappingModelExpressible<T>) sqmInterpretation.getSqmParameterMappingModelTypeResolutions().get(parameter);
}
}, session);
final JdbcSelect jdbcSelect = selectTranslator.translate(jdbcParameterBindings, executionContext.getQueryOptions());
return new CacheableSqmInterpretation(sqmInterpretation.getSqlAst(), jdbcSelect, tableGroupAccess, jdbcParamsXref, sqmInterpretation.getSqmParameterMappingModelTypeResolutions(), jdbcParameterBindings);
}
use of org.hibernate.sql.ast.tree.select.SelectStatement in project hibernate-orm by hibernate.
the class InsertExecutionDelegate method insertRootTable.
private void insertRootTable(String tableExpression, int rows, String[] keyColumns, ExecutionContext executionContext) {
final TableReference updatingTableReference = updatingTableGroup.getTableReference(updatingTableGroup.getNavigablePath(), tableExpression, true, true);
final IdentifierGenerator identifierGenerator = entityDescriptor.getEntityPersister().getIdentifierGenerator();
final List<Assignment> assignments = assignmentsByTable.get(updatingTableReference);
if ((assignments == null || assignments.isEmpty()) && !(identifierGenerator instanceof PostInsertIdentifierGenerator)) {
throw new IllegalStateException("There must be at least a single root table assignment");
}
final NamedTableReference dmlTableReference = resolveUnionTableReference(updatingTableReference, tableExpression);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Create the SQL AST and convert it into a JdbcOperation
final QuerySpec querySpec = new QuerySpec(true);
final NamedTableReference temporaryTableReference = new NamedTableReference(insertStatement.getTargetTable().getTableExpression(), updatingTableReference.getIdentificationVariable(), false, sessionFactory);
final TableGroupImpl temporaryTableGroup = new TableGroupImpl(updatingTableGroup.getNavigablePath(), null, temporaryTableReference, entityDescriptor);
querySpec.getFromClause().addRoot(temporaryTableGroup);
final InsertStatement insertStatement = new InsertStatement(dmlTableReference);
insertStatement.setSourceSelectStatement(querySpec);
for (Assignment assignment : assignments) {
insertStatement.addTargetColumnReferences(assignment.getAssignable().getColumnReferences());
for (ColumnReference columnReference : assignment.getAssignable().getColumnReferences()) {
querySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, new ColumnReference(updatingTableReference.getIdentificationVariable(), columnReference.getColumnExpression(), false, null, null, columnReference.getJdbcMapping(), sessionFactory)));
}
}
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
final Map<Object, Object> entityTableToRootIdentity;
if (identifierGenerator instanceof PostInsertIdentifierGenerator) {
final BasicEntityIdentifierMapping identifierMapping = (BasicEntityIdentifierMapping) entityDescriptor.getIdentifierMapping();
final QuerySpec idSelectQuerySpec = new QuerySpec(true);
idSelectQuerySpec.getFromClause().addRoot(temporaryTableGroup);
final ColumnReference columnReference = new ColumnReference((String) null, TemporaryTable.ENTITY_TABLE_IDENTITY_COLUMN, false, null, null, identifierMapping.getJdbcMapping(), sessionFactory);
idSelectQuerySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, columnReference));
idSelectQuerySpec.addSortSpecification(new SortSpecification(columnReference, SortOrder.ASCENDING));
final SelectStatement selectStatement = new SelectStatement(idSelectQuerySpec, Collections.singletonList(new BasicFetch<>(0, null, null, identifierMapping, null, FetchTiming.IMMEDIATE, null)));
final JdbcSelect jdbcSelect = jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory().buildSelectTranslator(sessionFactory, selectStatement).translate(null, executionContext.getQueryOptions());
final List<Object> list = jdbcServices.getJdbcSelectExecutor().list(jdbcSelect, JdbcParameterBindings.NO_BINDINGS, executionContext, null, ListResultsConsumer.UniqueSemantic.NONE);
entityTableToRootIdentity = new LinkedHashMap<>(list.size());
for (Object o : list) {
entityTableToRootIdentity.put(o, null);
}
querySpec.applyPredicate(new ComparisonPredicate(columnReference, ComparisonOperator.EQUAL, new JdbcParameterImpl(identifierMapping.getJdbcMapping())));
} else {
entityTableToRootIdentity = null;
if (identifierGenerator instanceof OptimizableGenerator) {
final Optimizer optimizer = ((OptimizableGenerator) identifierGenerator).getOptimizer();
// but only if the target paths don't already contain the id
if (optimizer != null && optimizer.getIncrementSize() > 1 && insertStatement.getTargetColumnReferences().stream().noneMatch(c -> keyColumns[0].equals(c.getColumnExpression()))) {
final BasicEntityIdentifierMapping identifierMapping = (BasicEntityIdentifierMapping) entityDescriptor.getIdentifierMapping();
final JdbcParameter rowNumber = new JdbcParameterImpl(identifierMapping.getJdbcMapping());
final JdbcParameter rootIdentity = new JdbcParameterImpl(identifierMapping.getJdbcMapping());
final List<Assignment> temporaryTableAssignments = new ArrayList<>(1);
final ColumnReference idColumnReference = new ColumnReference((String) null, identifierMapping, sessionFactory);
temporaryTableAssignments.add(new Assignment(idColumnReference, rootIdentity));
final TemporaryTableColumn rowNumberColumn = entityTable.getColumns().get(entityTable.getColumns().size() - 1);
final UpdateStatement updateStatement = new UpdateStatement(temporaryTableReference, temporaryTableAssignments, new ComparisonPredicate(new ColumnReference((String) null, rowNumberColumn.getColumnName(), false, null, null, rowNumberColumn.getJdbcMapping(), sessionFactory), ComparisonOperator.EQUAL, rowNumber));
final JdbcUpdate jdbcUpdate = jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory().buildUpdateTranslator(sessionFactory, updateStatement).translate(null, executionContext.getQueryOptions());
final JdbcParameterBindings updateBindings = new JdbcParameterBindingsImpl(2);
for (int i = 0; i < rows; i++) {
updateBindings.addBinding(rowNumber, new JdbcParameterBindingImpl(rowNumberColumn.getJdbcMapping(), i + 1));
updateBindings.addBinding(rootIdentity, new JdbcParameterBindingImpl(identifierMapping.getJdbcMapping(), identifierGenerator.generate(executionContext.getSession(), null)));
jdbcServices.getJdbcMutationExecutor().execute(jdbcUpdate, updateBindings, sql -> executionContext.getSession().getJdbcCoordinator().getStatementPreparer().prepareStatement(sql), (integer, preparedStatement) -> {
}, executionContext);
}
insertStatement.addTargetColumnReferences(new ColumnReference((String) null, keyColumns[0], false, null, null, identifierMapping.getJdbcMapping(), sessionFactory));
querySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, new ColumnReference(updatingTableReference.getIdentificationVariable(), idColumnReference.getColumnExpression(), false, null, null, idColumnReference.getJdbcMapping(), sessionFactory)));
}
}
}
final JdbcInsert jdbcInsert = jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory().buildInsertTranslator(sessionFactory, insertStatement).translate(null, executionContext.getQueryOptions());
if (identifierGenerator instanceof PostInsertIdentifierGenerator) {
final PostInsertIdentifierGenerator generator = (PostInsertIdentifierGenerator) identifierGenerator;
final boolean generatedKeysEnabled = sessionFactory.getSessionFactoryOptions().isGetGeneratedKeysEnabled();
final InsertGeneratedIdentifierDelegate identifierDelegate = generator.getInsertGeneratedIdentifierDelegate((PostInsertIdentityPersister) entityDescriptor.getEntityPersister(), jdbcServices.getDialect(), generatedKeysEnabled);
final String finalSql = identifierDelegate.prepareIdentifierGeneratingInsert(jdbcInsert.getSql());
final BasicEntityIdentifierMapping identifierMapping = (BasicEntityIdentifierMapping) entityDescriptor.getIdentifierMapping();
final ValueBinder jdbcValueBinder = identifierMapping.getJdbcMapping().getJdbcValueBinder();
for (Map.Entry<Object, Object> entry : entityTableToRootIdentity.entrySet()) {
final Object rootIdentity = identifierDelegate.performInsert(finalSql, executionContext.getSession(), new Binder() {
@Override
public void bindValues(PreparedStatement ps) throws SQLException {
jdbcValueBinder.bind(ps, entry.getKey(), 1, executionContext.getSession());
}
@Override
public Object getEntity() {
return null;
}
});
entry.setValue(rootIdentity);
}
final JdbcParameter entityIdentity = new JdbcParameterImpl(identifierMapping.getJdbcMapping());
final JdbcParameter rootIdentity = new JdbcParameterImpl(identifierMapping.getJdbcMapping());
final List<Assignment> temporaryTableAssignments = new ArrayList<>(1);
temporaryTableAssignments.add(new Assignment(new ColumnReference((String) null, identifierMapping, sessionFactory), rootIdentity));
final UpdateStatement updateStatement = new UpdateStatement(temporaryTableReference, temporaryTableAssignments, new ComparisonPredicate(new ColumnReference((String) null, TemporaryTable.ENTITY_TABLE_IDENTITY_COLUMN, false, null, null, identifierMapping.getJdbcMapping(), sessionFactory), ComparisonOperator.EQUAL, entityIdentity));
final JdbcUpdate jdbcUpdate = jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory().buildUpdateTranslator(sessionFactory, updateStatement).translate(null, executionContext.getQueryOptions());
final JdbcParameterBindings updateBindings = new JdbcParameterBindingsImpl(2);
for (Map.Entry<Object, Object> entry : entityTableToRootIdentity.entrySet()) {
updateBindings.addBinding(entityIdentity, new JdbcParameterBindingImpl(identifierMapping.getJdbcMapping(), entry.getKey()));
updateBindings.addBinding(rootIdentity, new JdbcParameterBindingImpl(identifierMapping.getJdbcMapping(), entry.getValue()));
jdbcServices.getJdbcMutationExecutor().execute(jdbcUpdate, updateBindings, sql -> executionContext.getSession().getJdbcCoordinator().getStatementPreparer().prepareStatement(sql), (integer, preparedStatement) -> {
}, executionContext);
}
} else {
jdbcServices.getJdbcMutationExecutor().execute(jdbcInsert, JdbcParameterBindings.NO_BINDINGS, sql -> executionContext.getSession().getJdbcCoordinator().getStatementPreparer().prepareStatement(sql), (integer, preparedStatement) -> {
}, executionContext);
}
}
use of org.hibernate.sql.ast.tree.select.SelectStatement in project hibernate-orm by hibernate.
the class MatchingIdSelectionHelper method selectMatchingIds.
/**
* Centralized selection of ids matching the restriction of the DELETE
* or UPDATE SQM query
*/
public static List<Object> selectMatchingIds(SqmDeleteOrUpdateStatement sqmMutationStatement, DomainParameterXref domainParameterXref, DomainQueryExecutionContext executionContext) {
final SessionFactoryImplementor factory = executionContext.getSession().getFactory();
final EntityMappingType entityDescriptor = factory.getRuntimeMetamodels().getEntityMappingType(sqmMutationStatement.getTarget().getModel().getHibernateEntityName());
final MultiTableSqmMutationConverter sqmConverter = new MultiTableSqmMutationConverter(entityDescriptor, sqmMutationStatement, sqmMutationStatement.getTarget(), domainParameterXref, executionContext.getQueryOptions(), executionContext.getSession().getLoadQueryInfluencers(), executionContext.getQueryParameterBindings(), factory);
final Map<SqmParameter, List<JdbcParameter>> parameterResolutions;
if (domainParameterXref.getSqmParameterCount() == 0) {
parameterResolutions = Collections.emptyMap();
} else {
parameterResolutions = new IdentityHashMap<>();
}
final Predicate restriction = sqmConverter.visitWhereClause(sqmMutationStatement.getWhereClause(), columnReference -> {
}, (sqmParam, mappingType, jdbcParameters) -> parameterResolutions.put(sqmParam, jdbcParameters));
final SelectStatement matchingIdSelection = generateMatchingIdSelectStatement(entityDescriptor, sqmMutationStatement, true, restriction, sqmConverter, executionContext, factory);
sqmConverter.getProcessingStateStack().push(new SqlAstQueryPartProcessingStateImpl(matchingIdSelection.getQuerySpec(), sqmConverter.getCurrentProcessingState(), sqmConverter.getSqlAstCreationState(), sqmConverter.getCurrentClauseStack()::getCurrent, true));
entityDescriptor.visitSubTypeAttributeMappings(attribute -> {
if (attribute instanceof PluralAttributeMapping) {
final PluralAttributeMapping pluralAttribute = (PluralAttributeMapping) attribute;
if (pluralAttribute.getSeparateCollectionTable() != null) {
// Ensure that the FK target columns are available
final boolean useFkTarget = !(pluralAttribute.getKeyDescriptor().getTargetPart() instanceof EntityIdentifierMapping);
if (useFkTarget) {
final TableGroup mutatingTableGroup = sqmConverter.getMutatingTableGroup();
pluralAttribute.getKeyDescriptor().getTargetPart().applySqlSelections(mutatingTableGroup.getNavigablePath(), mutatingTableGroup, sqmConverter, (selection, jdbcMapping) -> {
matchingIdSelection.getDomainResultDescriptors().add(new BasicResult<>(selection.getValuesArrayPosition(), null, jdbcMapping.getJavaTypeDescriptor()));
});
}
}
}
});
sqmConverter.getProcessingStateStack().pop();
final JdbcServices jdbcServices = factory.getJdbcServices();
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
final SqlAstTranslator<JdbcSelect> sqlAstSelectTranslator = jdbcEnvironment.getSqlAstTranslatorFactory().buildSelectTranslator(factory, matchingIdSelection);
final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(executionContext.getQueryParameterBindings(), domainParameterXref, SqmUtil.generateJdbcParamsXref(domainParameterXref, sqmConverter), factory.getRuntimeMetamodels().getMappingMetamodel(), navigablePath -> sqmConverter.getMutatingTableGroup(), new SqmParameterMappingModelResolutionAccess() {
@Override
@SuppressWarnings("unchecked")
public <T> MappingModelExpressible<T> getResolvedMappingModelType(SqmParameter<T> parameter) {
return (MappingModelExpressible<T>) sqmConverter.getSqmParameterMappingModelExpressibleResolutions().get(parameter);
}
}, executionContext.getSession());
final LockOptions lockOptions = executionContext.getQueryOptions().getLockOptions();
final LockMode lockMode = lockOptions.getLockMode();
// Acquire a WRITE lock for the rows that are about to be modified
lockOptions.setLockMode(LockMode.WRITE);
// Visit the table joins and reset the lock mode if we encounter OUTER joins that are not supported
if (!jdbcEnvironment.getDialect().supportsOuterJoinForUpdate()) {
matchingIdSelection.getQuerySpec().getFromClause().visitTableJoins(tableJoin -> {
if (tableJoin.getJoinType() != SqlAstJoinType.INNER) {
lockOptions.setLockMode(lockMode);
}
});
}
final JdbcSelect idSelectJdbcOperation = sqlAstSelectTranslator.translate(jdbcParameterBindings, executionContext.getQueryOptions());
lockOptions.setLockMode(lockMode);
return jdbcServices.getJdbcSelectExecutor().list(idSelectJdbcOperation, jdbcParameterBindings, SqmJdbcExecutionContextAdapter.omittingLockingAndPaging(executionContext), row -> row[0], ListResultsConsumer.UniqueSemantic.FILTER);
}
Aggregations