Search in sources :

Example 16 with DomainResult

use of org.hibernate.sql.results.graph.DomainResult in project hibernate-orm by hibernate.

the class MatchingIdSelectionHelper method generateMatchingIdSelectStatement.

/**
 * @asciidoc
 *
 * Generates a query-spec for selecting all ids matching the restriction defined as part
 * of the user's update/delete query.  This query-spec is generally used:
 *
 * 		* to select all the matching ids via JDBC - see {@link MatchingIdSelectionHelper#selectMatchingIds}
 * 		* as a sub-query restriction to insert rows into an "id table"
 */
public static SelectStatement generateMatchingIdSelectStatement(EntityMappingType targetEntityDescriptor, SqmDeleteOrUpdateStatement sqmStatement, boolean queryRoot, Predicate restriction, MultiTableSqmMutationConverter sqmConverter, DomainQueryExecutionContext executionContext, SessionFactoryImplementor sessionFactory) {
    final EntityDomainType entityDomainType = sqmStatement.getTarget().getModel();
    if (log.isTraceEnabled()) {
        log.tracef("Starting generation of entity-id SQM selection - %s", entityDomainType.getHibernateEntityName());
    }
    final QuerySpec idSelectionQuery = new QuerySpec(queryRoot, 1);
    idSelectionQuery.applyPredicate(restriction);
    final TableGroup mutatingTableGroup = sqmConverter.getMutatingTableGroup();
    idSelectionQuery.getFromClause().addRoot(mutatingTableGroup);
    final List<DomainResult<?>> domainResults = new ArrayList<>();
    sqmConverter.getProcessingStateStack().push(new SqlAstQueryPartProcessingStateImpl(idSelectionQuery, sqmConverter.getCurrentProcessingState(), sqmConverter.getSqlAstCreationState(), sqmConverter.getCurrentClauseStack()::getCurrent, false));
    targetEntityDescriptor.getIdentifierMapping().applySqlSelections(mutatingTableGroup.getNavigablePath(), mutatingTableGroup, sqmConverter, (selection, jdbcMapping) -> {
        domainResults.add(new BasicResult<>(selection.getValuesArrayPosition(), null, jdbcMapping.getJavaTypeDescriptor()));
    });
    sqmConverter.getProcessingStateStack().pop();
    targetEntityDescriptor.getEntityPersister().applyBaseRestrictions(idSelectionQuery::applyPredicate, mutatingTableGroup, true, executionContext.getSession().getLoadQueryInfluencers().getEnabledFilters(), null, sqmConverter);
    return new SelectStatement(idSelectionQuery, domainResults);
}
Also used : SqlAstQueryPartProcessingStateImpl(org.hibernate.query.sqm.sql.internal.SqlAstQueryPartProcessingStateImpl) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) ArrayList(java.util.ArrayList) DomainResult(org.hibernate.sql.results.graph.DomainResult) EntityDomainType(org.hibernate.metamodel.model.domain.EntityDomainType) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec)

Example 17 with DomainResult

use of org.hibernate.sql.results.graph.DomainResult in project hibernate-orm by hibernate.

the class ResultSetMappingImpl method resolve.

@Override
public JdbcValuesMapping resolve(JdbcValuesMetadata jdbcResultsMetadata, SessionFactoryImplementor sessionFactory) {
    final int numberOfResults;
    final int rowSize = jdbcResultsMetadata.getColumnCount();
    if (resultBuilders == null) {
        numberOfResults = rowSize;
    } else {
        numberOfResults = resultBuilders.size();
    }
    final List<SqlSelection> sqlSelections = new ArrayList<>(rowSize);
    final List<DomainResult<?>> domainResults = new ArrayList<>(numberOfResults);
    final DomainResultCreationStateImpl creationState = new DomainResultCreationStateImpl(mappingIdentifier, jdbcResultsMetadata, legacyFetchBuilders, sqlSelections::add, sessionFactory);
    for (int i = 0; i < numberOfResults; i++) {
        final ResultBuilder resultBuilder = resultBuilders != null ? resultBuilders.get(i) : null;
        final DomainResult<?> domainResult;
        if (resultBuilder == null) {
            domainResult = makeImplicitDomainResult(i, sqlSelections::add, jdbcResultsMetadata, sessionFactory);
        } else {
            domainResult = resultBuilder.buildResult(jdbcResultsMetadata, domainResults.size(), creationState.getLegacyFetchResolver()::resolve, creationState);
        }
        if (domainResult.containsAnyNonScalarResults()) {
            creationState.disallowPositionalSelections();
        }
        domainResults.add(domainResult);
    }
    // As people should be able to just run native queries and work with tuples
    if (resultBuilders != null) {
        final Set<String> knownDuplicateAliases = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
        if (resultBuilders.size() == 1 && domainResults.size() == 1 && domainResults.get(0) instanceof EntityResult) {
            // Special case for result set mappings that just fetch a single polymorphic entity
            final EntityResult entityResult = (EntityResult) domainResults.get(0);
            final boolean polymorphic = entityResult.getReferencedMappingContainer().getEntityPersister().getEntityMetamodel().isPolymorphic();
            // If we don't do that, there is no way to fetch joined inheritance entities
            if (polymorphic && (legacyFetchBuilders == null || legacyFetchBuilders.isEmpty()) && !hasJoinFetches(entityResult.getFetches())) {
                final Set<String> aliases = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
                final AbstractEntityPersister entityPersister = (AbstractEntityPersister) entityResult.getReferencedMappingContainer().getEntityPersister();
                for (String[] columns : entityPersister.getContraintOrderedTableKeyColumnClosure()) {
                    addColumns(aliases, knownDuplicateAliases, columns);
                }
                addColumn(aliases, knownDuplicateAliases, entityPersister.getDiscriminatorColumnName());
                addColumn(aliases, knownDuplicateAliases, entityPersister.getVersionColumnName());
                for (int i = 0; i < entityPersister.countSubclassProperties(); i++) {
                    addColumns(aliases, knownDuplicateAliases, entityPersister.getSubclassPropertyColumnNames(i));
                }
            }
        }
        final String[] aliases = new String[rowSize];
        final Map<String, Boolean> aliasHasDuplicates = new HashMap<>(rowSize);
        for (int i = 0; i < rowSize; i++) {
            aliasHasDuplicates.compute(aliases[i] = jdbcResultsMetadata.resolveColumnName(i + 1), (k, v) -> v == null ? Boolean.FALSE : Boolean.TRUE);
        }
        // Only check for duplicates for the selections that we actually use
        for (SqlSelection sqlSelection : sqlSelections) {
            final String alias = aliases[sqlSelection.getValuesArrayPosition()];
            if (!knownDuplicateAliases.contains(alias) && aliasHasDuplicates.get(alias) == Boolean.TRUE) {
                throw new NonUniqueDiscoveredSqlAliasException("Encountered a duplicated sql alias [" + alias + "] during auto-discovery of a native-sql query");
            }
        }
    }
    return new JdbcValuesMappingImpl(sqlSelections, domainResults, rowSize, creationState.getRegisteredLockModes());
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) DomainResult(org.hibernate.sql.results.graph.DomainResult) NonUniqueDiscoveredSqlAliasException(org.hibernate.loader.NonUniqueDiscoveredSqlAliasException) EntityResult(org.hibernate.sql.results.graph.entity.EntityResult) SqlSelection(org.hibernate.sql.ast.spi.SqlSelection) TreeSet(java.util.TreeSet) AbstractEntityPersister(org.hibernate.persister.entity.AbstractEntityPersister)

Example 18 with DomainResult

use of org.hibernate.sql.results.graph.DomainResult in project hibernate-orm by hibernate.

the class CriteriaEntityGraphTest method assertDomainResult.

// util methods for verifying 'domain-result' graph ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void assertDomainResult(SelectStatement sqlAst, Class<?> expectedEntityJpaClass, String expectedAttributeName, Class<?> expectedAttributeEntityJpaClass, Consumer<EntityFetch> entityFetchConsumer) {
    assertThat(sqlAst.getDomainResultDescriptors(), hasSize(1));
    final DomainResult domainResult = sqlAst.getDomainResultDescriptors().get(0);
    assertThat(domainResult, instanceOf(EntityResult.class));
    final EntityResult entityResult = (EntityResult) domainResult;
    assertThat(entityResult.getReferencedModePart().getJavaType().getJavaTypeClass(), assignableTo(expectedEntityJpaClass));
    assertThat(entityResult.getFetches(), hasSize(1));
    final Fetch fetch = entityResult.getFetches().get(0);
    assertThat(fetch, instanceOf(EntityFetch.class));
    final EntityFetch entityFetch = (EntityFetch) fetch;
    assertThat(entityFetch.getFetchedMapping().getFetchableName(), is(expectedAttributeName));
    assertThat(entityFetch.getReferencedModePart().getJavaType().getJavaTypeClass(), assignableTo(expectedAttributeEntityJpaClass));
    entityFetchConsumer.accept(entityFetch);
}
Also used : DelayedCollectionFetch(org.hibernate.sql.results.graph.collection.internal.DelayedCollectionFetch) Fetch(org.hibernate.sql.results.graph.Fetch) EntityFetch(org.hibernate.sql.results.graph.entity.EntityFetch) EntityFetch(org.hibernate.sql.results.graph.entity.EntityFetch) DomainResult(org.hibernate.sql.results.graph.DomainResult) EntityResult(org.hibernate.sql.results.graph.entity.EntityResult)

Example 19 with DomainResult

use of org.hibernate.sql.results.graph.DomainResult in project hibernate-orm by hibernate.

the class EntityGraphLoadPlanBuilderTest method assertDomainResult.

// util methods for verifying 'domain-result' graph ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void assertDomainResult(SelectStatement sqlAst, Class<?> expectedEntityJpaClass, String expectedAttributeName, Class<?> expectedAttributeEntityJpaClass, Consumer<EntityFetch> entityFetchConsumer) {
    assertThat(sqlAst.getDomainResultDescriptors(), hasSize(1));
    final DomainResult domainResult = sqlAst.getDomainResultDescriptors().get(0);
    assertThat(domainResult, instanceOf(EntityResult.class));
    final EntityResult entityResult = (EntityResult) domainResult;
    assertThat(entityResult.getReferencedModePart().getJavaType().getJavaTypeClass(), assignableTo(expectedEntityJpaClass));
    assertThat(entityResult.getFetches(), hasSize(1));
    final Fetch fetch = entityResult.getFetches().get(0);
    assertThat(fetch, instanceOf(EntityFetch.class));
    final EntityFetch entityFetch = (EntityFetch) fetch;
    assertThat(entityFetch.getFetchedMapping().getFetchableName(), is(expectedAttributeName));
    assertThat(entityFetch.getReferencedModePart().getJavaType().getJavaTypeClass(), assignableTo(expectedAttributeEntityJpaClass));
    entityFetchConsumer.accept(entityFetch);
}
Also used : DelayedCollectionFetch(org.hibernate.sql.results.graph.collection.internal.DelayedCollectionFetch) Fetch(org.hibernate.sql.results.graph.Fetch) EntityFetch(org.hibernate.sql.results.graph.entity.EntityFetch) EntityFetch(org.hibernate.sql.results.graph.entity.EntityFetch) DomainResult(org.hibernate.sql.results.graph.DomainResult) EntityResult(org.hibernate.sql.results.graph.entity.EntityResult)

Example 20 with DomainResult

use of org.hibernate.sql.results.graph.DomainResult in project hibernate-orm by hibernate.

the class HqlEntityGraphTest method assertDomainResult.

// util methods for verifying 'domain-result' graph ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void assertDomainResult(SelectStatement sqlAst, Class<?> expectedEntityJpaClass, String expectedAttributeName, Class<?> expectedAttributeEntityJpaClass, Consumer<EntityFetch> entityFetchConsumer) {
    assertThat(sqlAst.getDomainResultDescriptors(), hasSize(1));
    final DomainResult domainResult = sqlAst.getDomainResultDescriptors().get(0);
    assertThat(domainResult, instanceOf(EntityResult.class));
    final EntityResult entityResult = (EntityResult) domainResult;
    assertThat(entityResult.getReferencedModePart().getJavaType().getJavaTypeClass(), assignableTo(expectedEntityJpaClass));
    assertThat(entityResult.getFetches(), hasSize(1));
    final Fetch fetch = entityResult.getFetches().get(0);
    assertThat(fetch, instanceOf(EntityFetch.class));
    final EntityFetch entityFetch = (EntityFetch) fetch;
    assertThat(entityFetch.getFetchedMapping().getFetchableName(), is(expectedAttributeName));
    assertThat(entityFetch.getReferencedModePart().getJavaType().getJavaTypeClass(), assignableTo(expectedAttributeEntityJpaClass));
    entityFetchConsumer.accept(entityFetch);
}
Also used : DelayedCollectionFetch(org.hibernate.sql.results.graph.collection.internal.DelayedCollectionFetch) Fetch(org.hibernate.sql.results.graph.Fetch) EntityFetch(org.hibernate.sql.results.graph.entity.EntityFetch) EntityFetch(org.hibernate.sql.results.graph.entity.EntityFetch) DomainResult(org.hibernate.sql.results.graph.DomainResult) EntityResult(org.hibernate.sql.results.graph.entity.EntityResult)

Aggregations

DomainResult (org.hibernate.sql.results.graph.DomainResult)22 Fetch (org.hibernate.sql.results.graph.Fetch)11 TableGroup (org.hibernate.sql.ast.tree.from.TableGroup)9 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)8 EntityMappingType (org.hibernate.metamodel.mapping.EntityMappingType)7 SqlSelection (org.hibernate.sql.ast.spi.SqlSelection)7 EntityResult (org.hibernate.sql.results.graph.entity.EntityResult)7 BiConsumer (java.util.function.BiConsumer)6 JdbcMapping (org.hibernate.metamodel.mapping.JdbcMapping)6 SqlExpressionResolver (org.hibernate.sql.ast.spi.SqlExpressionResolver)6 SelectStatement (org.hibernate.sql.ast.tree.select.SelectStatement)6 DomainResultCreationState (org.hibernate.sql.results.graph.DomainResultCreationState)6 BasicResult (org.hibernate.sql.results.graph.basic.BasicResult)6 SharedSessionContractImplementor (org.hibernate.engine.spi.SharedSessionContractImplementor)5 IndexedConsumer (org.hibernate.mapping.IndexedConsumer)5 MappingType (org.hibernate.metamodel.mapping.MappingType)5 NavigableRole (org.hibernate.metamodel.model.domain.NavigableRole)5 EntityPersister (org.hibernate.persister.entity.EntityPersister)5 NavigablePath (org.hibernate.spi.NavigablePath)5 Clause (org.hibernate.sql.ast.Clause)5