Search in sources :

Example 6 with JdbcParameterBindings

use of org.hibernate.sql.exec.spi.JdbcParameterBindings in project hibernate-orm by hibernate.

the class CteInsertHandler method execute.

@Override
public int execute(DomainQueryExecutionContext executionContext) {
    final SqmInsertStatement<?> sqmInsertStatement = getSqmStatement();
    final SessionFactoryImplementor factory = executionContext.getSession().getFactory();
    final EntityPersister entityDescriptor = getEntityDescriptor().getEntityPersister();
    final String explicitDmlTargetAlias;
    if (sqmInsertStatement.getTarget().getExplicitAlias() == null) {
        explicitDmlTargetAlias = "dml_target";
    } else {
        explicitDmlTargetAlias = sqmInsertStatement.getTarget().getExplicitAlias();
    }
    final MultiTableSqmMutationConverter sqmConverter = new MultiTableSqmMutationConverter(entityDescriptor, sqmInsertStatement, sqmInsertStatement.getTarget(), explicitDmlTargetAlias, domainParameterXref, executionContext.getQueryOptions(), executionContext.getSession().getLoadQueryInfluencers(), executionContext.getQueryParameterBindings(), factory);
    final TableGroup insertingTableGroup = sqmConverter.getMutatingTableGroup();
    final Map<SqmParameter<?>, List<List<JdbcParameter>>> parameterResolutions;
    if (domainParameterXref.getSqmParameterCount() == 0) {
        parameterResolutions = Collections.emptyMap();
    } else {
        parameterResolutions = new IdentityHashMap<>();
    }
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // visit the insertion target using our special converter, collecting
    // information about the target paths
    final int size = sqmStatement.getInsertionTargetPaths().size();
    final List<Map.Entry<SqmCteTableColumn, Assignment>> targetPathColumns = new ArrayList<>(size);
    final List<SqmCteTableColumn> targetPathSqmCteColumns = new ArrayList<>(size);
    final Map<SqmParameter<?>, MappingModelExpressible<?>> paramTypeResolutions = new LinkedHashMap<>();
    final NamedTableReference entityTableReference = new NamedTableReference(cteTable.getCteName(), TemporaryTable.DEFAULT_ALIAS, true, sessionFactory);
    final InsertStatement insertStatement = new InsertStatement(entityTableReference);
    final BaseSqmToSqlAstConverter.AdditionalInsertValues additionalInsertValues = sqmConverter.visitInsertionTargetPaths((assignable, columnReferences) -> {
        // Find a matching cte table column and set that at the current index
        for (SqmCteTableColumn column : cteTable.getColumns()) {
            if (column.getType() == ((Expression) assignable).getExpressionType()) {
                insertStatement.addTargetColumnReferences(columnReferences);
                targetPathSqmCteColumns.add(column);
                targetPathColumns.add(new AbstractMap.SimpleEntry<>(column, new Assignment(assignable, (Expression) assignable)));
                return;
            }
        }
        throw new IllegalStateException("Couldn't find matching cte column for: " + ((Expression) assignable).getExpressionType());
    }, sqmInsertStatement, entityDescriptor, insertingTableGroup, (sqmParameter, mappingType, jdbcParameters) -> {
        parameterResolutions.computeIfAbsent(sqmParameter, k -> new ArrayList<>(1)).add(jdbcParameters);
        paramTypeResolutions.put(sqmParameter, mappingType);
    });
    final boolean assignsId = targetPathSqmCteColumns.contains(cteTable.getColumns().get(0));
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Create the statement that represent the source for the entity cte
    final Stack<SqlAstProcessingState> processingStateStack = sqmConverter.getProcessingStateStack();
    final SqlAstProcessingState oldState = processingStateStack.pop();
    final Statement queryStatement;
    if (sqmInsertStatement instanceof SqmInsertSelectStatement) {
        final QueryPart queryPart = sqmConverter.visitQueryPart(((SqmInsertSelectStatement<?>) sqmInsertStatement).getSelectQueryPart());
        queryPart.visitQuerySpecs(querySpec -> {
            // in which case we will fill the row_number column instead of the id column
            if (additionalInsertValues.applySelections(querySpec, sessionFactory)) {
                final SqmCteTableColumn rowNumberColumn = cteTable.getColumns().get(cteTable.getColumns().size() - 1);
                final ColumnReference columnReference = new ColumnReference((String) null, rowNumberColumn.getColumnName(), false, null, null, (JdbcMapping) rowNumberColumn.getType(), sessionFactory);
                insertStatement.getTargetColumnReferences().set(insertStatement.getTargetColumnReferences().size() - 1, columnReference);
                targetPathSqmCteColumns.set(targetPathSqmCteColumns.size() - 1, rowNumberColumn);
            }
            if (!assignsId && entityDescriptor.getIdentifierGenerator() instanceof PostInsertIdentifierGenerator) {
                final BasicType<Integer> rowNumberType = sessionFactory.getTypeConfiguration().getBasicTypeForJavaType(Integer.class);
                querySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, new Over<>(new SelfRenderingFunctionSqlAstExpression("row_number", (appender, args, walker) -> appender.appendSql("row_number()"), Collections.emptyList(), rowNumberType, rowNumberType), Collections.emptyList(), Collections.emptyList())));
            }
        });
        queryStatement = new SelectStatement(queryPart);
    } else {
        final List<SqmValues> sqmValuesList = ((SqmInsertValuesStatement<?>) sqmInsertStatement).getValuesList();
        final List<Values> valuesList = new ArrayList<>(sqmValuesList.size());
        for (SqmValues sqmValues : sqmValuesList) {
            final Values values = sqmConverter.visitValues(sqmValues);
            additionalInsertValues.applyValues(values);
            valuesList.add(values);
        }
        final QuerySpec querySpec = new QuerySpec(true);
        final NavigablePath navigablePath = new NavigablePath(entityDescriptor.getRootPathName());
        final List<String> columnNames = new ArrayList<>(targetPathColumns.size());
        final String valuesAlias = insertingTableGroup.getPrimaryTableReference().getIdentificationVariable();
        for (Map.Entry<SqmCteTableColumn, Assignment> entry : targetPathColumns) {
            for (ColumnReference columnReference : entry.getValue().getAssignable().getColumnReferences()) {
                columnNames.add(columnReference.getColumnExpression());
                querySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, columnReference.getQualifier().equals(valuesAlias) ? columnReference : new ColumnReference(valuesAlias, columnReference.getColumnExpression(), false, null, null, columnReference.getJdbcMapping(), null)));
            }
        }
        final ValuesTableGroup valuesTableGroup = new ValuesTableGroup(navigablePath, entityDescriptor.getEntityPersister(), valuesList, insertingTableGroup.getPrimaryTableReference().getIdentificationVariable(), columnNames, true, factory);
        querySpec.getFromClause().addRoot(valuesTableGroup);
        queryStatement = new SelectStatement(querySpec);
    }
    processingStateStack.push(oldState);
    sqmConverter.pruneTableGroupJoins();
    if (!assignsId && entityDescriptor.getIdentifierGenerator() instanceof PostInsertIdentifierGenerator) {
        // Add the row number to the assignments
        final SqmCteTableColumn rowNumberColumn = cteTable.getColumns().get(cteTable.getColumns().size() - 1);
        final ColumnReference columnReference = new ColumnReference((String) null, rowNumberColumn.getColumnName(), false, null, null, (JdbcMapping) rowNumberColumn.getType(), sessionFactory);
        insertStatement.getTargetColumnReferences().add(columnReference);
        targetPathSqmCteColumns.add(rowNumberColumn);
    }
    final CteTable entityCteTable = BaseSqmToSqlAstConverter.createCteTable(getCteTable(), targetPathSqmCteColumns, factory);
    // Create the main query spec that will return the count of rows
    final QuerySpec querySpec = new QuerySpec(true, 1);
    final List<DomainResult<?>> domainResults = new ArrayList<>(1);
    final SelectStatement statement = new SelectStatement(querySpec, domainResults);
    final CteStatement entityCte;
    if (additionalInsertValues.requiresRowNumberIntermediate()) {
        final CteTable fullEntityCteTable = BaseSqmToSqlAstConverter.createCteTable(getCteTable(), factory);
        final String baseTableName = "base_" + entityCteTable.getTableExpression();
        final CteStatement baseEntityCte = new CteStatement(entityCteTable.withName(baseTableName), queryStatement, // The query cte will be reused multiple times
        CteMaterialization.MATERIALIZED);
        statement.addCteStatement(baseEntityCte);
        final CteColumn rowNumberColumn = fullEntityCteTable.getCteColumns().get(fullEntityCteTable.getCteColumns().size() - 1);
        final ColumnReference rowNumberColumnReference = new ColumnReference("e", rowNumberColumn.getColumnExpression(), false, null, null, rowNumberColumn.getJdbcMapping(), factory);
        final CteColumn idColumn = fullEntityCteTable.getCteColumns().get(0);
        final BasicValuedMapping idType = (BasicValuedMapping) idColumn.getJdbcMapping();
        final Optimizer optimizer = ((OptimizableGenerator) entityDescriptor.getIdentifierGenerator()).getOptimizer();
        final BasicValuedMapping integerType = (BasicValuedMapping) rowNumberColumn.getJdbcMapping();
        final Expression rowNumberMinusOneModuloIncrement = new BinaryArithmeticExpression(new BinaryArithmeticExpression(rowNumberColumnReference, BinaryArithmeticOperator.SUBTRACT, new QueryLiteral<>(1, (BasicValuedMapping) rowNumberColumn.getJdbcMapping()), integerType), BinaryArithmeticOperator.MODULO, new QueryLiteral<>(optimizer.getIncrementSize(), integerType), integerType);
        // Create the CTE that fetches a new sequence value for the row numbers that need it
        {
            final QuerySpec rowsWithSequenceQuery = new QuerySpec(true);
            rowsWithSequenceQuery.getFromClause().addRoot(new CteTableGroup(new NamedTableReference(baseTableName, "e", false, factory)));
            rowsWithSequenceQuery.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, rowNumberColumnReference));
            final String fragment = ((BulkInsertionCapableIdentifierGenerator) entityDescriptor.getIdentifierGenerator()).determineBulkInsertionIdentifierGenerationSelectFragment(sessionFactory.getSqlStringGenerationContext());
            rowsWithSequenceQuery.getSelectClause().addSqlSelection(new SqlSelectionImpl(2, 1, new SelfRenderingSqlFragmentExpression(fragment)));
            rowsWithSequenceQuery.applyPredicate(new ComparisonPredicate(rowNumberMinusOneModuloIncrement, ComparisonOperator.EQUAL, new QueryLiteral<>(0, integerType)));
            final CteTable rowsWithSequenceCteTable = new CteTable(ROW_NUMBERS_WITH_SEQUENCE_VALUE, Arrays.asList(rowNumberColumn, idColumn), sessionFactory);
            final SelectStatement rowsWithSequenceStatement = new SelectStatement(rowsWithSequenceQuery);
            final CteStatement rowsWithSequenceCte = new CteStatement(rowsWithSequenceCteTable, rowsWithSequenceStatement, // The query cte will be reused multiple times
            CteMaterialization.MATERIALIZED);
            statement.addCteStatement(rowsWithSequenceCte);
        }
        // Create the CTE that represents the entity cte
        {
            final QuerySpec entityQuery = new QuerySpec(true);
            final NavigablePath navigablePath = new NavigablePath(baseTableName);
            final TableGroup baseTableGroup = new TableGroupImpl(navigablePath, null, new NamedTableReference(baseTableName, "e", false, factory), null);
            final TableGroup rowsWithSequenceTableGroup = new CteTableGroup(new NamedTableReference(ROW_NUMBERS_WITH_SEQUENCE_VALUE, "t", false, factory));
            baseTableGroup.addTableGroupJoin(new TableGroupJoin(rowsWithSequenceTableGroup.getNavigablePath(), SqlAstJoinType.LEFT, rowsWithSequenceTableGroup, new ComparisonPredicate(new BinaryArithmeticExpression(rowNumberColumnReference, BinaryArithmeticOperator.SUBTRACT, rowNumberMinusOneModuloIncrement, integerType), ComparisonOperator.EQUAL, new ColumnReference("t", rowNumberColumn.getColumnExpression(), false, null, null, rowNumberColumn.getJdbcMapping(), factory))));
            entityQuery.getFromClause().addRoot(baseTableGroup);
            entityQuery.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, new BinaryArithmeticExpression(new ColumnReference("t", idColumn.getColumnExpression(), false, null, null, idColumn.getJdbcMapping(), factory), BinaryArithmeticOperator.ADD, new BinaryArithmeticExpression(rowNumberColumnReference, BinaryArithmeticOperator.SUBTRACT, new ColumnReference("t", rowNumberColumn.getColumnExpression(), false, null, null, rowNumberColumn.getJdbcMapping(), factory), integerType), idType)));
            final CteTable finalEntityCteTable;
            if (targetPathSqmCteColumns.contains(getCteTable().getColumns().get(0))) {
                finalEntityCteTable = entityCteTable;
            } else {
                targetPathSqmCteColumns.add(0, getCteTable().getColumns().get(0));
                finalEntityCteTable = BaseSqmToSqlAstConverter.createCteTable(getCteTable(), targetPathSqmCteColumns, factory);
            }
            final List<CteColumn> cteColumns = finalEntityCteTable.getCteColumns();
            for (int i = 1; i < cteColumns.size(); i++) {
                final CteColumn cteColumn = cteColumns.get(i);
                entityQuery.getSelectClause().addSqlSelection(new SqlSelectionImpl(i + 1, i, new ColumnReference("e", cteColumn.getColumnExpression(), false, null, null, cteColumn.getJdbcMapping(), factory)));
            }
            final SelectStatement entityStatement = new SelectStatement(entityQuery);
            entityCte = new CteStatement(finalEntityCteTable, entityStatement, // The query cte will be reused multiple times
            CteMaterialization.MATERIALIZED);
            statement.addCteStatement(entityCte);
        }
    } else if (!assignsId && entityDescriptor.getIdentifierGenerator() instanceof PostInsertIdentifierGenerator) {
        final String baseTableName = "base_" + entityCteTable.getTableExpression();
        final CteStatement baseEntityCte = new CteStatement(entityCteTable.withName(baseTableName), queryStatement, // The query cte will be reused multiple times
        CteMaterialization.MATERIALIZED);
        statement.addCteStatement(baseEntityCte);
        targetPathSqmCteColumns.add(0, cteTable.getColumns().get(0));
        final CteTable finalEntityCteTable = BaseSqmToSqlAstConverter.createCteTable(getCteTable(), targetPathSqmCteColumns, factory);
        final QuerySpec finalQuerySpec = new QuerySpec(true);
        final SelectStatement finalQueryStatement = new SelectStatement(finalQuerySpec);
        entityCte = new CteStatement(finalEntityCteTable, finalQueryStatement, // The query cte will be reused multiple times
        CteMaterialization.MATERIALIZED);
    } else {
        entityCte = new CteStatement(entityCteTable, queryStatement, // The query cte will be reused multiple times
        CteMaterialization.MATERIALIZED);
        statement.addCteStatement(entityCte);
    }
    // Add all CTEs
    final String baseInsertCte = addDmlCtes(statement, entityCte, targetPathColumns, assignsId, sqmConverter, parameterResolutions, factory);
    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(// We want to return the insertion count of the base table
    baseInsertCte, CTE_TABLE_IDENTIFIER, false, factory)));
    // Execute the statement
    final JdbcServices jdbcServices = factory.getJdbcServices();
    final SqlAstTranslator<JdbcSelect> translator = jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory().buildSelectTranslator(factory, statement);
    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>) paramTypeResolutions.get(parameter);
        }
    }, executionContext.getSession());
    final JdbcSelect select = translator.translate(jdbcParameterBindings, executionContext.getQueryOptions());
    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 : CollectionHelper(org.hibernate.internal.util.collections.CollectionHelper) Arrays(java.util.Arrays) EntityPersister(org.hibernate.persister.entity.EntityPersister) Statement(org.hibernate.sql.ast.tree.Statement) SqlExpressible(org.hibernate.metamodel.mapping.SqlExpressible) BasicType(org.hibernate.type.BasicType) SqmCteTable(org.hibernate.query.sqm.tree.cte.SqmCteTable) SqmInsertValuesStatement(org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement) TableGroupJoin(org.hibernate.sql.ast.tree.from.TableGroupJoin) CteStatement(org.hibernate.sql.ast.tree.cte.CteStatement) Joinable(org.hibernate.persister.entity.Joinable) EntityMappingType(org.hibernate.metamodel.mapping.EntityMappingType) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) Identifier(org.hibernate.boot.model.naming.Identifier) SqmJdbcExecutionContextAdapter(org.hibernate.query.sqm.internal.SqmJdbcExecutionContextAdapter) ComparisonPredicate(org.hibernate.sql.ast.tree.predicate.ComparisonPredicate) SqmUtil(org.hibernate.query.sqm.internal.SqmUtil) PostInsertIdentifierGenerator(org.hibernate.id.PostInsertIdentifierGenerator) Map(java.util.Map) ComparisonOperator(org.hibernate.query.sqm.ComparisonOperator) TableReferenceJoin(org.hibernate.sql.ast.tree.from.TableReferenceJoin) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) SqmInsertSelectStatement(org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement) IdentifierGenerator(org.hibernate.id.IdentifierGenerator) Assignment(org.hibernate.sql.ast.tree.update.Assignment) IdentityHashMap(java.util.IdentityHashMap) SelfRenderingSqlFragmentExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression) SelfRenderingFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression) TypeConfiguration(org.hibernate.type.spi.TypeConfiguration) Optimizer(org.hibernate.id.enhanced.Optimizer) DomainResult(org.hibernate.sql.results.graph.DomainResult) BasicValuedMapping(org.hibernate.metamodel.mapping.BasicValuedMapping) Expression(org.hibernate.sql.ast.tree.expression.Expression) BaseSqmToSqlAstConverter(org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter) NavigablePath(org.hibernate.spi.NavigablePath) BasicResult(org.hibernate.sql.results.graph.basic.BasicResult) SqlAstProcessingState(org.hibernate.sql.ast.spi.SqlAstProcessingState) EntityIdentifierMapping(org.hibernate.metamodel.mapping.EntityIdentifierMapping) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) InsertHandler(org.hibernate.query.sqm.mutation.internal.InsertHandler) List(java.util.List) Dialect(org.hibernate.dialect.Dialect) Over(org.hibernate.sql.ast.tree.expression.Over) SqmParameter(org.hibernate.query.sqm.tree.expression.SqmParameter) AbstractEntityPersister(org.hibernate.persister.entity.AbstractEntityPersister) InsertStatement(org.hibernate.sql.ast.tree.insert.InsertStatement) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) TableGroupImpl(org.hibernate.query.results.TableGroupImpl) JdbcMapping(org.hibernate.metamodel.mapping.JdbcMapping) CteContainer(org.hibernate.sql.ast.tree.cte.CteContainer) CteMaterialization(org.hibernate.sql.ast.tree.cte.CteMaterialization) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) OptimizableGenerator(org.hibernate.id.OptimizableGenerator) SemanticException(org.hibernate.query.SemanticException) SortOrder(org.hibernate.query.sqm.SortOrder) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings) SortSpecification(org.hibernate.sql.ast.tree.select.SortSpecification) ArrayList(java.util.ArrayList) TableReference(org.hibernate.sql.ast.tree.from.TableReference) LinkedHashMap(java.util.LinkedHashMap) CteTable(org.hibernate.sql.ast.tree.cte.CteTable) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) MultiTableSqmMutationConverter(org.hibernate.query.sqm.mutation.internal.MultiTableSqmMutationConverter) SqmParameterMappingModelResolutionAccess(org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess) CteColumn(org.hibernate.sql.ast.tree.cte.CteColumn) UnionTableReference(org.hibernate.sql.ast.tree.from.UnionTableReference) BiConsumer(java.util.function.BiConsumer) BinaryArithmeticExpression(org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression) BinaryArithmeticOperator(org.hibernate.query.sqm.BinaryArithmeticOperator) ValuesTableGroup(org.hibernate.sql.ast.tree.from.ValuesTableGroup) Values(org.hibernate.sql.ast.tree.insert.Values) BulkInsertionCapableIdentifierGenerator(org.hibernate.id.BulkInsertionCapableIdentifierGenerator) TemporaryTable(org.hibernate.dialect.temptable.TemporaryTable) ListResultsConsumer(org.hibernate.sql.results.spi.ListResultsConsumer) SqmStar(org.hibernate.query.sqm.tree.expression.SqmStar) CteTableGroup(org.hibernate.sql.ast.tree.cte.CteTableGroup) SqlAstTranslator(org.hibernate.sql.ast.SqlAstTranslator) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) QueryLiteral(org.hibernate.sql.ast.tree.expression.QueryLiteral) DomainQueryExecutionContext(org.hibernate.query.spi.DomainQueryExecutionContext) SqmCteTableColumn(org.hibernate.query.sqm.tree.cte.SqmCteTableColumn) AbstractMap(java.util.AbstractMap) JdbcParameter(org.hibernate.sql.ast.tree.expression.JdbcParameter) SqmInsertStatement(org.hibernate.query.sqm.tree.insert.SqmInsertStatement) QueryPart(org.hibernate.sql.ast.tree.select.QueryPart) SqlAstJoinType(org.hibernate.sql.ast.SqlAstJoinType) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) Stack(org.hibernate.internal.util.collections.Stack) DomainParameterXref(org.hibernate.query.sqm.internal.DomainParameterXref) Collections(java.util.Collections) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) JdbcSelect(org.hibernate.sql.exec.spi.JdbcSelect) SqmValues(org.hibernate.query.sqm.tree.insert.SqmValues) CteColumn(org.hibernate.sql.ast.tree.cte.CteColumn) QueryPart(org.hibernate.sql.ast.tree.select.QueryPart) OptimizableGenerator(org.hibernate.id.OptimizableGenerator) ArrayList(java.util.ArrayList) Values(org.hibernate.sql.ast.tree.insert.Values) SqmValues(org.hibernate.query.sqm.tree.insert.SqmValues) InsertStatement(org.hibernate.sql.ast.tree.insert.InsertStatement) SqmInsertStatement(org.hibernate.query.sqm.tree.insert.SqmInsertStatement) LinkedHashMap(java.util.LinkedHashMap) ValuesTableGroup(org.hibernate.sql.ast.tree.from.ValuesTableGroup) AbstractMap(java.util.AbstractMap) Assignment(org.hibernate.sql.ast.tree.update.Assignment) CteStatement(org.hibernate.sql.ast.tree.cte.CteStatement) List(java.util.List) ArrayList(java.util.ArrayList) ValuesTableGroup(org.hibernate.sql.ast.tree.from.ValuesTableGroup) CteTableGroup(org.hibernate.sql.ast.tree.cte.CteTableGroup) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) SqmParameterMappingModelResolutionAccess(org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) DomainResult(org.hibernate.sql.results.graph.DomainResult) CteTableGroup(org.hibernate.sql.ast.tree.cte.CteTableGroup) BinaryArithmeticExpression(org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression) SelfRenderingFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) LinkedHashMap(java.util.LinkedHashMap) AbstractMap(java.util.AbstractMap) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) EntityPersister(org.hibernate.persister.entity.EntityPersister) AbstractEntityPersister(org.hibernate.persister.entity.AbstractEntityPersister) NavigablePath(org.hibernate.spi.NavigablePath) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) Optimizer(org.hibernate.id.enhanced.Optimizer) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) ComparisonPredicate(org.hibernate.sql.ast.tree.predicate.ComparisonPredicate) TableGroupJoin(org.hibernate.sql.ast.tree.from.TableGroupJoin) SqlAstProcessingState(org.hibernate.sql.ast.spi.SqlAstProcessingState) Over(org.hibernate.sql.ast.tree.expression.Over) SqmInsertSelectStatement(org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) SqmCteTable(org.hibernate.query.sqm.tree.cte.SqmCteTable) CteTable(org.hibernate.sql.ast.tree.cte.CteTable) QueryLiteral(org.hibernate.sql.ast.tree.expression.QueryLiteral) BasicResult(org.hibernate.sql.results.graph.basic.BasicResult) SqmValues(org.hibernate.query.sqm.tree.insert.SqmValues) TableGroupImpl(org.hibernate.query.results.TableGroupImpl) SqmInsertSelectStatement(org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement) BaseSqmToSqlAstConverter(org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter) SelfRenderingSqlFragmentExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression) JdbcSelect(org.hibernate.sql.exec.spi.JdbcSelect) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) JdbcParameter(org.hibernate.sql.ast.tree.expression.JdbcParameter) Statement(org.hibernate.sql.ast.tree.Statement) SqmInsertValuesStatement(org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement) CteStatement(org.hibernate.sql.ast.tree.cte.CteStatement) SqmInsertSelectStatement(org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) InsertStatement(org.hibernate.sql.ast.tree.insert.InsertStatement) SqmInsertStatement(org.hibernate.query.sqm.tree.insert.SqmInsertStatement) SqmInsertValuesStatement(org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement) PostInsertIdentifierGenerator(org.hibernate.id.PostInsertIdentifierGenerator) BasicValuedMapping(org.hibernate.metamodel.mapping.BasicValuedMapping) SqmCteTableColumn(org.hibernate.query.sqm.tree.cte.SqmCteTableColumn) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) SelfRenderingSqlFragmentExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression) SelfRenderingFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression) Expression(org.hibernate.sql.ast.tree.expression.Expression) BinaryArithmeticExpression(org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) SqmParameter(org.hibernate.query.sqm.tree.expression.SqmParameter) MultiTableSqmMutationConverter(org.hibernate.query.sqm.mutation.internal.MultiTableSqmMutationConverter) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings)

Example 7 with JdbcParameterBindings

use of org.hibernate.sql.exec.spi.JdbcParameterBindings in project hibernate-orm by hibernate.

the class RestrictedDeleteExecutionDelegate method executeWithIdTable.

private int executeWithIdTable(Predicate predicate, TableGroup deletingTableGroup, Map<SqmParameter<?>, List<List<JdbcParameter>>> restrictionSqmParameterResolutions, Map<SqmParameter<?>, MappingModelExpressible<?>> paramTypeResolutions, ExecutionContext executionContext) {
    final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(executionContext.getQueryParameterBindings(), domainParameterXref, SqmUtil.generateJdbcParamsXref(domainParameterXref, () -> restrictionSqmParameterResolutions), sessionFactory.getRuntimeMetamodels().getMappingMetamodel(), navigablePath -> deletingTableGroup, new SqmParameterMappingModelResolutionAccess() {

        @Override
        @SuppressWarnings("unchecked")
        public <T> MappingModelExpressible<T> getResolvedMappingModelType(SqmParameter<T> parameter) {
            return (MappingModelExpressible<T>) paramTypeResolutions.get(parameter);
        }
    }, executionContext.getSession());
    ExecuteWithTemporaryTableHelper.performBeforeTemporaryTableUseActions(idTable, executionContext);
    try {
        return executeUsingIdTable(predicate, executionContext, jdbcParameterBindings);
    } finally {
        ExecuteWithTemporaryTableHelper.performAfterTemporaryTableUseActions(idTable, sessionUidAccess, afterUseAction, executionContext);
    }
}
Also used : SqmParameterMappingModelResolutionAccess(org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings)

Example 8 with JdbcParameterBindings

use of org.hibernate.sql.exec.spi.JdbcParameterBindings in project hibernate-orm by hibernate.

the class RestrictedDeleteExecutionDelegate method executeWithoutIdTable.

private int executeWithoutIdTable(Predicate suppliedPredicate, TableGroup tableGroup, Map<SqmParameter<?>, List<List<JdbcParameter>>> restrictionSqmParameterResolutions, Map<SqmParameter<?>, MappingModelExpressible<?>> paramTypeResolutions, SqlExpressionResolver sqlExpressionResolver, ExecutionContext executionContext) {
    assert entityDescriptor == entityDescriptor.getRootEntityDescriptor();
    final EntityPersister rootEntityPersister = entityDescriptor.getEntityPersister();
    final String rootTableName = ((Joinable) rootEntityPersister).getTableName();
    final NamedTableReference rootTableReference = (NamedTableReference) tableGroup.resolveTableReference(tableGroup.getNavigablePath(), rootTableName);
    final QuerySpec matchingIdSubQuerySpec = ExecuteWithoutIdTableHelper.createIdMatchingSubQuerySpec(tableGroup.getNavigablePath(), rootTableReference, suppliedPredicate, rootEntityPersister, sqlExpressionResolver, sessionFactory);
    final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(executionContext.getQueryParameterBindings(), domainParameterXref, SqmUtil.generateJdbcParamsXref(domainParameterXref, () -> restrictionSqmParameterResolutions), sessionFactory.getRuntimeMetamodels().getMappingMetamodel(), navigablePath -> tableGroup, new SqmParameterMappingModelResolutionAccess() {

        @Override
        @SuppressWarnings("unchecked")
        public <T> MappingModelExpressible<T> getResolvedMappingModelType(SqmParameter<T> parameter) {
            return (MappingModelExpressible<T>) paramTypeResolutions.get(parameter);
        }
    }, executionContext.getSession());
    SqmMutationStrategyHelper.cleanUpCollectionTables(entityDescriptor, (tableReference, attributeMapping) -> {
        // No need for a predicate if there is no supplied predicate i.e. this is a full cleanup
        if (suppliedPredicate == null) {
            return null;
        }
        final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
        final QuerySpec idSelectFkSubQuery;
        // todo (6.0): based on the location of the attribute mapping, we could prune the table group of the subquery
        if (fkDescriptor.getTargetPart() instanceof EntityIdentifierMapping) {
            idSelectFkSubQuery = matchingIdSubQuerySpec;
        } else {
            idSelectFkSubQuery = ExecuteWithoutIdTableHelper.createIdMatchingSubQuerySpec(tableGroup.getNavigablePath(), rootTableReference, suppliedPredicate, rootEntityPersister, sqlExpressionResolver, sessionFactory);
        }
        return new InSubQueryPredicate(MappingModelHelper.buildColumnReferenceExpression(fkDescriptor, null, sessionFactory), idSelectFkSubQuery, false);
    }, jdbcParameterBindings, executionContext);
    if (rootTableReference instanceof UnionTableReference) {
        final MutableInteger rows = new MutableInteger();
        entityDescriptor.visitConstraintOrderedTables((tableExpression, tableKeyColumnVisitationSupplier) -> {
            final NamedTableReference tableReference = new NamedTableReference(tableExpression, tableGroup.getPrimaryTableReference().getIdentificationVariable(), false, sessionFactory);
            final QuerySpec idMatchingSubQuerySpec;
            // No need for a predicate if there is no supplied predicate i.e. this is a full cleanup
            if (suppliedPredicate == null) {
                idMatchingSubQuerySpec = null;
            } else {
                idMatchingSubQuerySpec = matchingIdSubQuerySpec;
            }
            rows.plus(deleteFromNonRootTableWithoutIdTable(tableReference, tableKeyColumnVisitationSupplier, sqlExpressionResolver, tableGroup, idMatchingSubQuerySpec, jdbcParameterBindings, executionContext));
        });
        return rows.get();
    } else {
        entityDescriptor.visitConstraintOrderedTables((tableExpression, tableKeyColumnVisitationSupplier) -> {
            if (!tableExpression.equals(rootTableName)) {
                final NamedTableReference tableReference = (NamedTableReference) tableGroup.getTableReference(tableGroup.getNavigablePath(), tableExpression, true, true);
                final QuerySpec idMatchingSubQuerySpec;
                // No need for a predicate if there is no supplied predicate i.e. this is a full cleanup
                if (suppliedPredicate == null) {
                    idMatchingSubQuerySpec = null;
                } else {
                    idMatchingSubQuerySpec = matchingIdSubQuerySpec;
                }
                deleteFromNonRootTableWithoutIdTable(tableReference, tableKeyColumnVisitationSupplier, sqlExpressionResolver, tableGroup, idMatchingSubQuerySpec, jdbcParameterBindings, executionContext);
            }
        });
        return deleteFromRootTableWithoutIdTable(rootTableReference, suppliedPredicate, jdbcParameterBindings, executionContext);
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) SqmParameterMappingModelResolutionAccess(org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) InSubQueryPredicate(org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate) MutableInteger(org.hibernate.internal.util.MutableInteger) UnionTableReference(org.hibernate.sql.ast.tree.from.UnionTableReference) ForeignKeyDescriptor(org.hibernate.metamodel.mapping.ForeignKeyDescriptor) Joinable(org.hibernate.persister.entity.Joinable) EntityIdentifierMapping(org.hibernate.metamodel.mapping.EntityIdentifierMapping) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings)

Example 9 with JdbcParameterBindings

use of org.hibernate.sql.exec.spi.JdbcParameterBindings 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);
    }
}
Also used : CollectionHelper(org.hibernate.internal.util.collections.CollectionHelper) ExecutionContext(org.hibernate.sql.exec.spi.ExecutionContext) ValueBinder(org.hibernate.type.descriptor.ValueBinder) EntityMappingType(org.hibernate.metamodel.mapping.EntityMappingType) ComparisonPredicate(org.hibernate.sql.ast.tree.predicate.ComparisonPredicate) SqmUtil(org.hibernate.query.sqm.internal.SqmUtil) PostInsertIdentifierGenerator(org.hibernate.id.PostInsertIdentifierGenerator) Map(java.util.Map) JdbcParameterImpl(org.hibernate.sql.exec.internal.JdbcParameterImpl) Binder(org.hibernate.id.insert.Binder) ComparisonOperator(org.hibernate.query.sqm.ComparisonOperator) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) IdentifierGenerator(org.hibernate.id.IdentifierGenerator) Assignable(org.hibernate.sql.ast.tree.update.Assignable) Assignment(org.hibernate.sql.ast.tree.update.Assignment) Optimizer(org.hibernate.id.enhanced.Optimizer) PreparedStatement(java.sql.PreparedStatement) UpdateStatement(org.hibernate.sql.ast.tree.update.UpdateStatement) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) ArrayHelper(org.hibernate.internal.util.collections.ArrayHelper) List(java.util.List) JdbcUpdate(org.hibernate.sql.exec.spi.JdbcUpdate) SqmParameter(org.hibernate.query.sqm.tree.expression.SqmParameter) AbstractEntityPersister(org.hibernate.persister.entity.AbstractEntityPersister) InsertStatement(org.hibernate.sql.ast.tree.insert.InsertStatement) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) TemporaryTableColumn(org.hibernate.dialect.temptable.TemporaryTableColumn) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) BasicEntityIdentifierMapping(org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping) JdbcParameterBindingsImpl(org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl) TableGroupImpl(org.hibernate.query.results.TableGroupImpl) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) OptimizableGenerator(org.hibernate.id.OptimizableGenerator) Function(java.util.function.Function) SemanticException(org.hibernate.query.SemanticException) SortOrder(org.hibernate.query.sqm.SortOrder) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings) BasicFetch(org.hibernate.sql.results.graph.basic.BasicFetch) SortSpecification(org.hibernate.sql.ast.tree.select.SortSpecification) ArrayList(java.util.ArrayList) TableReference(org.hibernate.sql.ast.tree.from.TableReference) LinkedHashMap(java.util.LinkedHashMap) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) SQLException(java.sql.SQLException) MultiTableSqmMutationConverter(org.hibernate.query.sqm.mutation.internal.MultiTableSqmMutationConverter) JdbcInsert(org.hibernate.sql.exec.spi.JdbcInsert) SqmParameterMappingModelResolutionAccess(org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess) UnionTableReference(org.hibernate.sql.ast.tree.from.UnionTableReference) PostInsertIdentityPersister(org.hibernate.id.PostInsertIdentityPersister) FetchTiming(org.hibernate.engine.FetchTiming) InsertGeneratedIdentifierDelegate(org.hibernate.id.insert.InsertGeneratedIdentifierDelegate) TemporaryTable(org.hibernate.dialect.temptable.TemporaryTable) ListResultsConsumer(org.hibernate.sql.results.spi.ListResultsConsumer) ModelPartContainer(org.hibernate.metamodel.mapping.ModelPartContainer) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) DomainQueryExecutionContext(org.hibernate.query.spi.DomainQueryExecutionContext) JdbcParameter(org.hibernate.sql.ast.tree.expression.JdbcParameter) JdbcParameterBindingImpl(org.hibernate.sql.exec.internal.JdbcParameterBindingImpl) SqmInsertStatement(org.hibernate.query.sqm.tree.insert.SqmInsertStatement) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) DomainParameterXref(org.hibernate.query.sqm.internal.DomainParameterXref) Collections(java.util.Collections) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) JdbcSelect(org.hibernate.sql.exec.spi.JdbcSelect) SQLException(java.sql.SQLException) OptimizableGenerator(org.hibernate.id.OptimizableGenerator) Optimizer(org.hibernate.id.enhanced.Optimizer) ArrayList(java.util.ArrayList) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) TemporaryTableColumn(org.hibernate.dialect.temptable.TemporaryTableColumn) InsertStatement(org.hibernate.sql.ast.tree.insert.InsertStatement) SqmInsertStatement(org.hibernate.query.sqm.tree.insert.SqmInsertStatement) ComparisonPredicate(org.hibernate.sql.ast.tree.predicate.ComparisonPredicate) Assignment(org.hibernate.sql.ast.tree.update.Assignment) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) ValueBinder(org.hibernate.type.descriptor.ValueBinder) Binder(org.hibernate.id.insert.Binder) TableReference(org.hibernate.sql.ast.tree.from.TableReference) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) UnionTableReference(org.hibernate.sql.ast.tree.from.UnionTableReference) JdbcUpdate(org.hibernate.sql.exec.spi.JdbcUpdate) TableGroupImpl(org.hibernate.query.results.TableGroupImpl) JdbcParameterImpl(org.hibernate.sql.exec.internal.JdbcParameterImpl) BasicFetch(org.hibernate.sql.results.graph.basic.BasicFetch) JdbcSelect(org.hibernate.sql.exec.spi.JdbcSelect) UpdateStatement(org.hibernate.sql.ast.tree.update.UpdateStatement) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) JdbcParameterBindingsImpl(org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl) JdbcParameter(org.hibernate.sql.ast.tree.expression.JdbcParameter) JdbcParameterBindingImpl(org.hibernate.sql.exec.internal.JdbcParameterBindingImpl) PreparedStatement(java.sql.PreparedStatement) BasicEntityIdentifierMapping(org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping) InsertGeneratedIdentifierDelegate(org.hibernate.id.insert.InsertGeneratedIdentifierDelegate) PostInsertIdentifierGenerator(org.hibernate.id.PostInsertIdentifierGenerator) JdbcInsert(org.hibernate.sql.exec.spi.JdbcInsert) SortSpecification(org.hibernate.sql.ast.tree.select.SortSpecification) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) ValueBinder(org.hibernate.type.descriptor.ValueBinder) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) PostInsertIdentifierGenerator(org.hibernate.id.PostInsertIdentifierGenerator) IdentifierGenerator(org.hibernate.id.IdentifierGenerator) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings)

Example 10 with JdbcParameterBindings

use of org.hibernate.sql.exec.spi.JdbcParameterBindings in project hibernate-orm by hibernate.

the class CollectionElementLoaderByIndex method load.

public Object load(Object key, Object index, SharedSessionContractImplementor session) {
    final SessionFactoryImplementor sessionFactory = session.getFactory();
    final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
    final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
    final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
    final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl(keyJdbcCount);
    int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(key, Clause.WHERE, attributeMapping.getKeyDescriptor(), jdbcParameters, session);
    offset += jdbcParameterBindings.registerParametersForEachJdbcValue(incrementIndexByBase(index), Clause.WHERE, offset, attributeMapping.getIndexDescriptor(), jdbcParameters, session);
    assert offset == jdbcParameters.size();
    final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator(sessionFactory, sqlAst).translate(jdbcParameterBindings, QueryOptions.NONE);
    List<Object> list = jdbcServices.getJdbcSelectExecutor().list(jdbcSelect, jdbcParameterBindings, new ExecutionContext() {

        @Override
        public SharedSessionContractImplementor getSession() {
            return session;
        }

        @Override
        public CollectionKey getCollectionKey() {
            return null;
        }

        @Override
        public QueryOptions getQueryOptions() {
            return QueryOptions.NONE;
        }

        @Override
        public String getQueryIdentifier(String sql) {
            return sql;
        }

        @Override
        public QueryParameterBindings getQueryParameterBindings() {
            return QueryParameterBindings.NO_PARAM_BINDINGS;
        }

        @Override
        public Callback getCallback() {
            return null;
        }
    }, RowTransformerStandardImpl.instance(), ListResultsConsumer.UniqueSemantic.FILTER);
    if (list.isEmpty()) {
        return null;
    }
    return list.get(0);
}
Also used : JdbcSelect(org.hibernate.sql.exec.spi.JdbcSelect) JdbcParameterBindingsImpl(org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) CollectionKey(org.hibernate.engine.spi.CollectionKey) JdbcEnvironment(org.hibernate.engine.jdbc.env.spi.JdbcEnvironment) QueryOptions(org.hibernate.query.spi.QueryOptions) SqlAstTranslatorFactory(org.hibernate.sql.ast.SqlAstTranslatorFactory) ExecutionContext(org.hibernate.sql.exec.spi.ExecutionContext) Callback(org.hibernate.sql.exec.spi.Callback) QueryParameterBindings(org.hibernate.query.spi.QueryParameterBindings) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings)

Aggregations

JdbcParameterBindings (org.hibernate.sql.exec.spi.JdbcParameterBindings)32 JdbcServices (org.hibernate.engine.jdbc.spi.JdbcServices)21 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)20 SharedSessionContractImplementor (org.hibernate.engine.spi.SharedSessionContractImplementor)19 JdbcParameterBindingsImpl (org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl)19 JdbcSelect (org.hibernate.sql.exec.spi.JdbcSelect)18 ArrayList (java.util.ArrayList)15 QueryParameterBindings (org.hibernate.query.spi.QueryParameterBindings)14 ExecutionContext (org.hibernate.sql.exec.spi.ExecutionContext)14 JdbcEnvironment (org.hibernate.engine.jdbc.env.spi.JdbcEnvironment)13 MappingModelExpressible (org.hibernate.metamodel.mapping.MappingModelExpressible)13 SelectStatement (org.hibernate.sql.ast.tree.select.SelectStatement)13 SqmParameterMappingModelResolutionAccess (org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess)12 SqlAstTranslatorFactory (org.hibernate.sql.ast.SqlAstTranslatorFactory)12 Callback (org.hibernate.sql.exec.spi.Callback)12 QueryOptions (org.hibernate.query.spi.QueryOptions)11 JdbcParameter (org.hibernate.sql.ast.tree.expression.JdbcParameter)11 List (java.util.List)8 SqmParameter (org.hibernate.query.sqm.tree.expression.SqmParameter)7 QuerySpec (org.hibernate.sql.ast.tree.select.QuerySpec)7