use of org.hibernate.query.sqm.internal.SqmJdbcExecutionContextAdapter in project hibernate-orm by hibernate.
the class InlineDeleteHandler method executeDelete.
private void executeDelete(String targetTableExpression, EntityMappingType entityDescriptor, Supplier<Consumer<SelectableConsumer>> tableKeyColumnsVisitationSupplier, List<Object> ids, int valueIndex, ModelPart valueModelPart, JdbcParameterBindings jdbcParameterBindings, DomainQueryExecutionContext executionContext) {
final NamedTableReference targetTableReference = new NamedTableReference(targetTableExpression, DeleteStatement.DEFAULT_ALIAS, false, sessionFactory);
final SqmJdbcExecutionContextAdapter executionContextAdapter = SqmJdbcExecutionContextAdapter.omittingLockingAndPaging(executionContext);
final Predicate matchingIdsPredicate = matchingIdsPredicateProducer.produceRestriction(ids, entityDescriptor, valueIndex, valueModelPart, targetTableReference, tableKeyColumnsVisitationSupplier, executionContextAdapter);
final DeleteStatement deleteStatement = new DeleteStatement(targetTableReference, matchingIdsPredicate);
final JdbcDelete jdbcOperation = sqlAstTranslatorFactory.buildDeleteTranslator(sessionFactory, deleteStatement).translate(jdbcParameterBindings, executionContext.getQueryOptions());
jdbcMutationExecutor.execute(jdbcOperation, jdbcParameterBindings, this::prepareQueryStatement, (integer, preparedStatement) -> {
}, executionContextAdapter);
}
use of org.hibernate.query.sqm.internal.SqmJdbcExecutionContextAdapter in project hibernate-orm by hibernate.
the class RestrictedDeleteExecutionDelegate method execute.
@Override
public int execute(DomainQueryExecutionContext executionContext) {
final EntityPersister entityDescriptor = sessionFactory.getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(sqmDelete.getTarget().getEntityName());
final String hierarchyRootTableName = ((Joinable) entityDescriptor).getTableName();
final TableGroup deletingTableGroup = converter.getMutatingTableGroup();
final TableReference hierarchyRootTableReference = deletingTableGroup.resolveTableReference(deletingTableGroup.getNavigablePath(), hierarchyRootTableName);
assert hierarchyRootTableReference != null;
final Map<SqmParameter<?>, List<List<JdbcParameter>>> parameterResolutions;
final Map<SqmParameter<?>, MappingModelExpressible<?>> paramTypeResolutions;
if (domainParameterXref.getSqmParameterCount() == 0) {
parameterResolutions = Collections.emptyMap();
paramTypeResolutions = Collections.emptyMap();
} else {
parameterResolutions = new IdentityHashMap<>();
paramTypeResolutions = new LinkedHashMap<>();
}
// Use the converter to interpret the where-clause. We do this for 2 reasons:
// 1) the resolved Predicate is ultimately the base for applying restriction to the deletes
// 2) we also inspect each ColumnReference that is part of the where-clause to see which
// table it comes from. if all of the referenced columns (if any at all) are from the root table
// we can perform all of the deletes without using an id-table
final MutableBoolean needsIdTableWrapper = new MutableBoolean(false);
final Predicate specifiedRestriction = converter.visitWhereClause(sqmDelete.getWhereClause(), columnReference -> {
if (!hierarchyRootTableReference.getIdentificationVariable().equals(columnReference.getQualifier())) {
needsIdTableWrapper.setValue(true);
}
}, (sqmParameter, mappingType, jdbcParameters) -> {
parameterResolutions.computeIfAbsent(sqmParameter, k -> new ArrayList<>(1)).add(jdbcParameters);
paramTypeResolutions.put(sqmParameter, mappingType);
});
final PredicateCollector predicateCollector = new PredicateCollector(specifiedRestriction);
entityDescriptor.applyBaseRestrictions((filterPredicate) -> {
needsIdTableWrapper.setValue(true);
predicateCollector.applyPredicate(filterPredicate);
}, deletingTableGroup, true, executionContext.getSession().getLoadQueryInfluencers().getEnabledFilters(), null, converter);
converter.pruneTableGroupJoins();
// We need an id table if we want to delete from an intermediate table to avoid FK violations
// The intermediate table has a FK to the root table, so we can't delete from the root table first
// Deleting from the intermediate table first also isn't possible,
// because that is the source for deletion in other tables, hence we need an id table
final boolean needsIdTable = needsIdTableWrapper.getValue() || entityDescriptor != entityDescriptor.getRootEntityDescriptor();
final SqmJdbcExecutionContextAdapter executionContextAdapter = SqmJdbcExecutionContextAdapter.omittingLockingAndPaging(executionContext);
if (needsIdTable) {
return executeWithIdTable(predicateCollector.getPredicate(), deletingTableGroup, parameterResolutions, paramTypeResolutions, executionContextAdapter);
} else {
return executeWithoutIdTable(predicateCollector.getPredicate(), deletingTableGroup, parameterResolutions, paramTypeResolutions, converter.getSqlExpressionResolver(), executionContextAdapter);
}
}
Aggregations