Search in sources :

Example 1 with SqmDeleteOrUpdateStatement

use of org.hibernate.query.sqm.tree.SqmDeleteOrUpdateStatement 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();
}
Also used : LockOptions(org.hibernate.LockOptions) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) ArrayList(java.util.ArrayList) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) LinkedHashMap(java.util.LinkedHashMap) InSubQueryPredicate(org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate) Predicate(org.hibernate.sql.ast.tree.predicate.Predicate) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) CteStatement(org.hibernate.sql.ast.tree.cte.CteStatement) List(java.util.List) ArrayList(java.util.ArrayList) EntityMappingType(org.hibernate.metamodel.mapping.EntityMappingType) SqmDeleteOrUpdateStatement(org.hibernate.query.sqm.tree.SqmDeleteOrUpdateStatement) JdbcSelect(org.hibernate.sql.exec.spi.JdbcSelect) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) DomainResult(org.hibernate.sql.results.graph.DomainResult) LockMode(org.hibernate.LockMode) CteTableGroup(org.hibernate.sql.ast.tree.cte.CteTableGroup) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) Expression(org.hibernate.sql.ast.tree.expression.Expression) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) SqmParameter(org.hibernate.query.sqm.tree.expression.SqmParameter) MultiTableSqmMutationConverter(org.hibernate.query.sqm.mutation.internal.MultiTableSqmMutationConverter) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings)

Aggregations

ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 LockMode (org.hibernate.LockMode)1 LockOptions (org.hibernate.LockOptions)1 JdbcServices (org.hibernate.engine.jdbc.spi.JdbcServices)1 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)1 EntityMappingType (org.hibernate.metamodel.mapping.EntityMappingType)1 MappingModelExpressible (org.hibernate.metamodel.mapping.MappingModelExpressible)1 MultiTableSqmMutationConverter (org.hibernate.query.sqm.mutation.internal.MultiTableSqmMutationConverter)1 SqmDeleteOrUpdateStatement (org.hibernate.query.sqm.tree.SqmDeleteOrUpdateStatement)1 SqmExpression (org.hibernate.query.sqm.tree.expression.SqmExpression)1 SqmParameter (org.hibernate.query.sqm.tree.expression.SqmParameter)1 CteStatement (org.hibernate.sql.ast.tree.cte.CteStatement)1 CteTableGroup (org.hibernate.sql.ast.tree.cte.CteTableGroup)1 Expression (org.hibernate.sql.ast.tree.expression.Expression)1 NamedTableReference (org.hibernate.sql.ast.tree.from.NamedTableReference)1 InSubQueryPredicate (org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate)1 Predicate (org.hibernate.sql.ast.tree.predicate.Predicate)1 QuerySpec (org.hibernate.sql.ast.tree.select.QuerySpec)1