use of org.hibernate.metamodel.mapping.EntityMappingType 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.metamodel.mapping.EntityMappingType in project hibernate-orm by hibernate.
the class ExecuteWithTemporaryTableHelper method saveMatchingIdsIntoIdTable.
public static int saveMatchingIdsIntoIdTable(MultiTableSqmMutationConverter sqmConverter, Predicate suppliedPredicate, TemporaryTable idTable, Function<SharedSessionContractImplementor, String> sessionUidAccess, JdbcParameterBindings jdbcParameterBindings, ExecutionContext executionContext) {
final SessionFactoryImplementor factory = executionContext.getSession().getFactory();
final TableGroup mutatingTableGroup = sqmConverter.getMutatingTableGroup();
assert mutatingTableGroup.getModelPart() instanceof EntityMappingType;
final EntityMappingType mutatingEntityDescriptor = (EntityMappingType) mutatingTableGroup.getModelPart();
final NamedTableReference idTableReference = new NamedTableReference(idTable.getTableExpression(), InsertStatement.DEFAULT_ALIAS, false, factory);
final InsertStatement idTableInsert = new InsertStatement(idTableReference);
for (int i = 0; i < idTable.getColumns().size(); i++) {
final TemporaryTableColumn column = idTable.getColumns().get(i);
idTableInsert.addTargetColumnReferences(new ColumnReference(idTableReference, column.getColumnName(), // id columns cannot be formulas and cannot have custom read and write expressions
false, null, null, column.getJdbcMapping(), factory));
}
final QuerySpec matchingIdSelection = new QuerySpec(true, 1);
idTableInsert.setSourceSelectStatement(matchingIdSelection);
matchingIdSelection.getFromClause().addRoot(mutatingTableGroup);
mutatingEntityDescriptor.getIdentifierMapping().forEachSelectable((jdbcPosition, selection) -> {
final TableReference tableReference = mutatingTableGroup.resolveTableReference(mutatingTableGroup.getNavigablePath(), selection.getContainingTableExpression());
matchingIdSelection.getSelectClause().addSqlSelection(new SqlSelectionImpl(jdbcPosition, jdbcPosition + 1, sqmConverter.getSqlExpressionResolver().resolveSqlExpression(SqlExpressionResolver.createColumnReferenceKey(tableReference, selection.getSelectionExpression()), sqlAstProcessingState -> new ColumnReference(tableReference, selection, factory))));
});
if (idTable.getSessionUidColumn() != null) {
final int jdbcPosition = matchingIdSelection.getSelectClause().getSqlSelections().size();
matchingIdSelection.getSelectClause().addSqlSelection(new SqlSelectionImpl(jdbcPosition, jdbcPosition + 1, new QueryLiteral<>(sessionUidAccess.apply(executionContext.getSession()), (BasicValuedMapping) idTable.getSessionUidColumn().getJdbcMapping())));
}
matchingIdSelection.applyPredicate(suppliedPredicate);
return saveIntoTemporaryTable(idTableInsert, jdbcParameterBindings, executionContext);
}
use of org.hibernate.metamodel.mapping.EntityMappingType 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);
}
use of org.hibernate.metamodel.mapping.EntityMappingType in project hibernate-orm by hibernate.
the class AbstractEntityPersister method interpretSqmMultiTableStrategy.
protected static SqmMultiTableMutationStrategy interpretSqmMultiTableStrategy(AbstractEntityPersister entityMappingDescriptor, MappingModelCreationProcess creationProcess) {
assert entityMappingDescriptor.hasMultipleTables();
EntityMappingType superMappingType = entityMappingDescriptor.getSuperMappingType();
if (superMappingType != null) {
SqmMultiTableMutationStrategy sqmMultiTableMutationStrategy = superMappingType.getSqmMultiTableMutationStrategy();
if (sqmMultiTableMutationStrategy != null) {
return sqmMultiTableMutationStrategy;
}
}
// we need the boot model so we can have access to the Table
final RootClass entityBootDescriptor = (RootClass) creationProcess.getCreationContext().getBootModel().getEntityBinding(entityMappingDescriptor.getRootEntityName());
return SqmMutationStrategyHelper.resolveStrategy(entityBootDescriptor, entityMappingDescriptor, creationProcess);
}
use of org.hibernate.metamodel.mapping.EntityMappingType in project hibernate-orm by hibernate.
the class EntityValuedPathInterpretation method from.
public static <T> EntityValuedPathInterpretation<T> from(NavigablePath navigablePath, TableGroup tableGroup, ModelPart resultModelPart, EntityValuedModelPart mapping, EntityValuedModelPart treatedMapping, SqmToSqlAstConverter sqlAstCreationState) {
final SqlExpressionResolver sqlExprResolver = sqlAstCreationState.getSqlExpressionResolver();
final SessionFactoryImplementor sessionFactory = sqlAstCreationState.getCreationContext().getSessionFactory();
final Expression sqlExpression;
if (resultModelPart == null) {
final EntityMappingType entityMappingType = mapping.getEntityMappingType();
final EntityIdentifierMapping identifierMapping = entityMappingType.getIdentifierMapping();
final EntityDiscriminatorMapping discriminatorMapping = entityMappingType.getDiscriminatorMapping();
final List<Expression> expressions = new ArrayList<>(entityMappingType.getJdbcTypeCount() + identifierMapping.getJdbcTypeCount() + (discriminatorMapping == null ? 0 : 1));
final TableGroup parentTableGroup = tableGroup;
final SelectableConsumer selectableConsumer = (selectionIndex, selectableMapping) -> {
final TableReference tableReference = parentTableGroup.resolveTableReference(navigablePath, selectableMapping.getContainingTableExpression(), false);
expressions.add(sqlExprResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, selectableMapping.getSelectionExpression()), processingState -> new ColumnReference(tableReference, selectableMapping, sessionFactory)));
};
identifierMapping.forEachSelectable(selectableConsumer);
if (discriminatorMapping != null) {
discriminatorMapping.forEachSelectable(selectableConsumer);
}
entityMappingType.forEachSelectable(selectableConsumer);
sqlExpression = new SqlTuple(expressions, entityMappingType);
} else {
if (resultModelPart instanceof BasicValuedModelPart) {
final BasicValuedModelPart basicValuedModelPart = (BasicValuedModelPart) resultModelPart;
final TableReference tableReference = tableGroup.resolveTableReference(navigablePath, basicValuedModelPart.getContainingTableExpression());
sqlExpression = sqlExprResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, basicValuedModelPart.getSelectionExpression()), processingState -> new ColumnReference(tableReference, basicValuedModelPart, sessionFactory));
} else {
final List<Expression> expressions = new ArrayList<>(resultModelPart.getJdbcTypeCount());
resultModelPart.forEachSelectable((selectionIndex, selectableMapping) -> {
final TableReference tableReference = tableGroup.resolveTableReference(navigablePath, selectableMapping.getContainingTableExpression());
expressions.add(sqlExprResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, selectableMapping.getSelectionExpression()), processingState -> new ColumnReference(tableReference, selectableMapping, sessionFactory)));
});
sqlExpression = new SqlTuple(expressions, resultModelPart);
}
}
return new EntityValuedPathInterpretation<>(sqlExpression, navigablePath, tableGroup, treatedMapping);
}
Aggregations