Search in sources :

Example 6 with ForeignKeyDescriptor

use of org.hibernate.metamodel.mapping.ForeignKeyDescriptor in project hibernate-orm by hibernate.

the class BaseSqmToSqlAstConverter method visitIsEmptyPredicate.

@Override
public Object visitIsEmptyPredicate(SqmEmptinessPredicate predicate) {
    prepareReusablePath(predicate.getPluralPath(), () -> null);
    final QuerySpec subQuerySpec = new QuerySpec(false, 1);
    final FromClauseAccess parentFromClauseAccess = getFromClauseAccess();
    final SqlAstProcessingStateImpl subQueryState = new SqlAstProcessingStateImpl(getCurrentProcessingState(), this, currentClauseStack::getCurrent);
    pushProcessingState(subQueryState);
    try {
        final SqmPluralValuedSimplePath<?> sqmPluralPath = predicate.getPluralPath();
        final NavigablePath pluralPathNavPath = sqmPluralPath.getNavigablePath();
        final NavigablePath parentNavPath = pluralPathNavPath.getParent();
        assert parentNavPath != null;
        final TableGroup parentTableGroup = parentFromClauseAccess.getTableGroup(parentNavPath);
        final SqlAliasBase sqlAliasBase = sqlAliasBaseManager.createSqlAliasBase(parentTableGroup.getGroupAlias());
        final TableGroup tableGroup = new CorrelatedTableGroup(parentTableGroup, sqlAliasBase, subQuerySpec, subQuerySpec::applyPredicate, creationContext.getSessionFactory());
        subQueryState.getSqlAstCreationState().getFromClauseAccess().registerTableGroup(parentNavPath, tableGroup);
        registerPluralTableGroupParts(tableGroup);
        final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) visitPluralValuedPath(sqmPluralPath).getExpressionType();
        // The creation of the table group join against the correlated table group
        // has the side effect that the from and where clause of the sub-query are set
        tableGroup.addTableGroupJoin(pluralAttributeMapping.createTableGroupJoin(pluralPathNavPath, tableGroup, sqmPluralPath.getExplicitAlias(), SqlAstJoinType.INNER, false, false, sqlAliasBaseManager, subQueryState, this, creationContext));
        final ForeignKeyDescriptor collectionKeyDescriptor = pluralAttributeMapping.getKeyDescriptor();
        final int jdbcTypeCount = collectionKeyDescriptor.getJdbcTypeCount();
        assert jdbcTypeCount > 0;
        final JdbcLiteral<Integer> jdbcLiteral = new JdbcLiteral<>(1, basicType(Integer.class));
        subQuerySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, jdbcLiteral));
        return new ExistsPredicate(subQuerySpec, !predicate.isNegated(), getBooleanType());
    } finally {
        popProcessingStateStack();
    }
}
Also used : NavigablePath(org.hibernate.query.spi.NavigablePath) VirtualTableGroup(org.hibernate.sql.ast.tree.from.VirtualTableGroup) LazyTableGroup(org.hibernate.sql.ast.tree.from.LazyTableGroup) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) CorrelatedTableGroup(org.hibernate.sql.ast.tree.from.CorrelatedTableGroup) CorrelatedPluralTableGroup(org.hibernate.sql.ast.tree.from.CorrelatedPluralTableGroup) PluralTableGroup(org.hibernate.sql.ast.tree.from.PluralTableGroup) QueryPartTableGroup(org.hibernate.sql.ast.tree.from.QueryPartTableGroup) ExistsPredicate(org.hibernate.sql.ast.tree.predicate.ExistsPredicate) SqmExistsPredicate(org.hibernate.query.sqm.tree.predicate.SqmExistsPredicate) PluralAttributeMapping(org.hibernate.metamodel.mapping.PluralAttributeMapping) SqlAstProcessingStateImpl(org.hibernate.query.sqm.sql.internal.SqlAstProcessingStateImpl) CorrelatedTableGroup(org.hibernate.sql.ast.tree.from.CorrelatedTableGroup) BigInteger(java.math.BigInteger) FromClauseAccess(org.hibernate.sql.ast.spi.FromClauseAccess) ForeignKeyDescriptor(org.hibernate.metamodel.mapping.ForeignKeyDescriptor) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) SqmQuerySpec(org.hibernate.query.sqm.tree.select.SqmQuerySpec) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) SqlAliasBase(org.hibernate.sql.ast.spi.SqlAliasBase) JdbcLiteral(org.hibernate.sql.ast.tree.expression.JdbcLiteral)

Example 7 with ForeignKeyDescriptor

use of org.hibernate.metamodel.mapping.ForeignKeyDescriptor 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 8 with ForeignKeyDescriptor

use of org.hibernate.metamodel.mapping.ForeignKeyDescriptor in project hibernate-orm by hibernate.

the class RestrictedDeleteExecutionDelegate method executeUsingIdTable.

private int executeUsingIdTable(Predicate predicate, ExecutionContext executionContext, JdbcParameterBindings jdbcParameterBindings) {
    final int rows = ExecuteWithTemporaryTableHelper.saveMatchingIdsIntoIdTable(converter, predicate, idTable, sessionUidAccess, jdbcParameterBindings, executionContext);
    final QuerySpec idTableIdentifierSubQuery = ExecuteWithTemporaryTableHelper.createIdTableSelectQuerySpec(idTable, sessionUidAccess, entityDescriptor, executionContext);
    SqmMutationStrategyHelper.cleanUpCollectionTables(entityDescriptor, (tableReference, attributeMapping) -> {
        final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
        final QuerySpec idTableFkSubQuery;
        if (fkDescriptor.getTargetPart() instanceof EntityIdentifierMapping) {
            idTableFkSubQuery = idTableIdentifierSubQuery;
        } else {
            idTableFkSubQuery = ExecuteWithTemporaryTableHelper.createIdTableSelectQuerySpec(idTable, fkDescriptor.getTargetPart(), sessionUidAccess, entityDescriptor, executionContext);
        }
        return new InSubQueryPredicate(MappingModelHelper.buildColumnReferenceExpression(fkDescriptor, null, sessionFactory), idTableFkSubQuery, false);
    }, JdbcParameterBindings.NO_BINDINGS, executionContext);
    entityDescriptor.visitConstraintOrderedTables((tableExpression, tableKeyColumnVisitationSupplier) -> deleteFromTableUsingIdTable(tableExpression, tableKeyColumnVisitationSupplier, idTableIdentifierSubQuery, executionContext));
    return rows;
}
Also used : ForeignKeyDescriptor(org.hibernate.metamodel.mapping.ForeignKeyDescriptor) InSubQueryPredicate(org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate) EntityIdentifierMapping(org.hibernate.metamodel.mapping.EntityIdentifierMapping) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec)

Example 9 with ForeignKeyDescriptor

use of org.hibernate.metamodel.mapping.ForeignKeyDescriptor in project hibernate-orm by hibernate.

the class EntityWithOneBidirectionalJoinTableAssociationTest method basicTest.

@Test
public void basicTest(SessionFactoryScope scope) {
    final EntityPersister parentDescriptor = scope.getSessionFactory().getMappingMetamodel().findEntityDescriptor(Parent.class);
    final ModelPart childAssociation = parentDescriptor.findSubPart("child");
    assertThat(childAssociation, instanceOf(ToOneAttributeMapping.class));
    final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) childAssociation;
    ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor();
    foreignKeyDescriptor.visitKeySelectables((columnIndex, selection) -> {
        assertThat(selection.getContainingTableExpression(), is("PARENT_CHILD"));
        assertThat(selection.getSelectionExpression(), is("child_id"));
    });
    foreignKeyDescriptor.visitTargetSelectables((columnIndex, selection) -> {
        assertThat(selection.getContainingTableExpression(), is("CHILD"));
        assertThat(selection.getSelectionExpression(), is("id"));
    });
    final EntityPersister childDescriptor = scope.getSessionFactory().getMappingMetamodel().findEntityDescriptor(Child.class);
    final ModelPart parentAssociation = childDescriptor.findSubPart("parent");
    assertThat(parentAssociation, instanceOf(ToOneAttributeMapping.class));
    final ToOneAttributeMapping parentAttributeMapping = (ToOneAttributeMapping) parentAssociation;
    foreignKeyDescriptor = parentAttributeMapping.getForeignKeyDescriptor();
    foreignKeyDescriptor.visitKeySelectables((columnIndex, selection) -> {
        assertThat(selection.getContainingTableExpression(), is("PARENT_CHILD"));
        assertThat(selection.getSelectionExpression(), is("parent_id"));
    });
    foreignKeyDescriptor.visitTargetSelectables((columnIndex, selection) -> {
        assertThat(selection.getContainingTableExpression(), is("PARENT"));
        assertThat(selection.getSelectionExpression(), is("id"));
    });
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) ModelPart(org.hibernate.metamodel.mapping.ModelPart) ToOneAttributeMapping(org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping) ForeignKeyDescriptor(org.hibernate.metamodel.mapping.ForeignKeyDescriptor) Test(org.junit.jupiter.api.Test)

Example 10 with ForeignKeyDescriptor

use of org.hibernate.metamodel.mapping.ForeignKeyDescriptor in project hibernate-orm by hibernate.

the class EntityWithBidirectionalAssociationTest method basicTest.

@Test
public void basicTest(SessionFactoryScope scope) {
    final EntityPersister parentDescriptor = scope.getSessionFactory().getMappingMetamodel().findEntityDescriptor(Parent.class);
    final ModelPart childAssociation = parentDescriptor.findSubPart("child");
    assertThat(childAssociation, instanceOf(ToOneAttributeMapping.class));
    final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) childAssociation;
    ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor();
    foreignKeyDescriptor.visitKeySelectables((columnIndex, selection) -> {
        assertThat(selection.getContainingTableExpression(), is("PARENT"));
        assertThat(selection.getSelectionExpression(), is("child_id"));
    });
    foreignKeyDescriptor.visitTargetSelectables((columnIndex, selection) -> {
        assertThat(selection.getContainingTableExpression(), is("CHILD"));
        assertThat(selection.getSelectionExpression(), is("id"));
    });
    final EntityPersister childDescriptor = scope.getSessionFactory().getMappingMetamodel().findEntityDescriptor(Child.class);
    final ModelPart parentAssociation = childDescriptor.findSubPart("parent");
    assertThat(parentAssociation, instanceOf(ToOneAttributeMapping.class));
    final ToOneAttributeMapping parentAttributeMapping = (ToOneAttributeMapping) parentAssociation;
    foreignKeyDescriptor = parentAttributeMapping.getForeignKeyDescriptor();
    foreignKeyDescriptor.visitKeySelectables((columnIndex, selection) -> {
        assertThat(selection.getContainingTableExpression(), is("PARENT"));
        assertThat(selection.getSelectionExpression(), is("child_id"));
    });
    foreignKeyDescriptor.visitTargetSelectables((columnIndex, selection) -> {
        assertThat(selection.getContainingTableExpression(), is("CHILD"));
        assertThat(selection.getSelectionExpression(), is("id"));
    });
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) ModelPart(org.hibernate.metamodel.mapping.ModelPart) ToOneAttributeMapping(org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping) ForeignKeyDescriptor(org.hibernate.metamodel.mapping.ForeignKeyDescriptor) Test(org.junit.jupiter.api.Test)

Aggregations

ForeignKeyDescriptor (org.hibernate.metamodel.mapping.ForeignKeyDescriptor)21 ModelPart (org.hibernate.metamodel.mapping.ModelPart)12 ToOneAttributeMapping (org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping)10 EntityPersister (org.hibernate.persister.entity.EntityPersister)9 EntityIdentifierMapping (org.hibernate.metamodel.mapping.EntityIdentifierMapping)7 NavigablePath (org.hibernate.query.spi.NavigablePath)7 QuerySpec (org.hibernate.sql.ast.tree.select.QuerySpec)7 AttributeMapping (org.hibernate.metamodel.mapping.AttributeMapping)6 PluralAttributeMapping (org.hibernate.metamodel.mapping.PluralAttributeMapping)5 Expression (org.hibernate.sql.ast.tree.expression.Expression)5 TableGroup (org.hibernate.sql.ast.tree.from.TableGroup)5 SqlSelectionImpl (org.hibernate.sql.results.internal.SqlSelectionImpl)5 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)4 BasicValuedModelPart (org.hibernate.metamodel.mapping.BasicValuedModelPart)4 SqlExpressionResolver (org.hibernate.sql.ast.spi.SqlExpressionResolver)4 ColumnReference (org.hibernate.sql.ast.tree.expression.ColumnReference)4 Test (org.junit.jupiter.api.Test)4 AbstractMap (java.util.AbstractMap)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3