Search in sources :

Example 1 with CollectionReferenceAliases

use of org.hibernate.loader.plan.exec.spi.CollectionReferenceAliases in project hibernate-orm by hibernate.

the class LoadQueryJoinAndFetchProcessor method processCollectionFetch.

private void processCollectionFetch(SelectStatementBuilder selectStatementBuilder, FetchSource fetchSource, CollectionAttributeFetch fetch, ReaderCollector readerCollector, FetchStatsImpl fetchStats) {
    fetchStats.processingFetch(fetch);
    if (!FetchStrategyHelper.isJoinFetched(fetch.getFetchStrategy())) {
        // not join fetched, so nothing else to do
        return;
    }
    final CollectionReferenceAliases aliases = aliasResolutionContext.resolveCollectionReferenceAliases(fetch.getQuerySpaceUid());
    final QueryableCollection queryableCollection = (QueryableCollection) fetch.getCollectionPersister();
    final Joinable joinableCollection = (Joinable) fetch.getCollectionPersister();
    if (fetch.getCollectionPersister().isManyToMany()) {
        // todo : better way to access `ownerTableAlias` here.
        // when processing the Join part of this we are able to look up the "lhs table alias" because we know
        // the 'lhs' QuerySpace.
        // 
        // Good idea to be able resolve a Join by lookup on the rhs and lhs uid?  If so, Fetch
        // for many-to-many we have 3 table aliases.  By way of example, consider a normal m-n: User<->Role
        // where User is the FetchOwner and Role (User.roles) is the Fetch.  We'd have:
        // 1) the owner's table : user
        final String ownerTableAlias = aliasResolutionContext.resolveSqlTableAliasFromQuerySpaceUid(fetchSource.getQuerySpaceUid());
        // 2) the m-n table : user_role
        final String collectionTableAlias = aliases.getCollectionTableAlias();
        // 3) the element table : role
        final String elementTableAlias = aliases.getElementTableAlias();
        // add select fragments from the collection table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        selectStatementBuilder.appendSelectClauseFragment(joinableCollection.selectFragment((Joinable) queryableCollection.getElementPersister(), elementTableAlias, collectionTableAlias, aliases.getEntityElementAliases().getColumnAliases().getSuffix(), aliases.getCollectionColumnAliases().getSuffix(), true));
        // add select fragments from the element entity table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        final OuterJoinLoadable elementPersister = (OuterJoinLoadable) queryableCollection.getElementPersister();
        selectStatementBuilder.appendSelectClauseFragment(elementPersister.selectFragment(elementTableAlias, aliases.getEntityElementAliases().getColumnAliases().getSuffix()));
        // add SQL ORDER-BY fragments
        final String manyToManyOrdering = queryableCollection.getManyToManyOrderByString(elementTableAlias);
        if (StringHelper.isNotEmpty(manyToManyOrdering)) {
            selectStatementBuilder.appendOrderByFragment(manyToManyOrdering);
        }
        final String ordering = queryableCollection.getSQLOrderByString(collectionTableAlias);
        if (StringHelper.isNotEmpty(ordering)) {
            selectStatementBuilder.appendOrderByFragment(ordering);
        }
        readerCollector.add(new EntityReferenceInitializerImpl((EntityReference) fetch.getElementGraph(), aliasResolutionContext.resolveEntityReferenceAliases(fetch.getElementGraph().getQuerySpaceUid())));
    } else {
        // select the "collection columns"
        selectStatementBuilder.appendSelectClauseFragment(queryableCollection.selectFragment(aliases.getElementTableAlias(), aliases.getCollectionColumnAliases().getSuffix()));
        if (fetch.getCollectionPersister().isOneToMany()) {
            // if the collection elements are entities, select the entity columns as well
            final OuterJoinLoadable elementPersister = (OuterJoinLoadable) queryableCollection.getElementPersister();
            selectStatementBuilder.appendSelectClauseFragment(elementPersister.selectFragment(aliases.getElementTableAlias(), aliases.getEntityElementAliases().getColumnAliases().getSuffix()));
            readerCollector.add(new EntityReferenceInitializerImpl((EntityReference) fetch.getElementGraph(), aliasResolutionContext.resolveEntityReferenceAliases(fetch.getElementGraph().getQuerySpaceUid())));
        }
        final String ordering = queryableCollection.getSQLOrderByString(aliases.getElementTableAlias());
        if (StringHelper.isNotEmpty(ordering)) {
            selectStatementBuilder.appendOrderByFragment(ordering);
        }
    }
    if (fetch.getElementGraph() != null) {
        processFetches(fetch.getElementGraph(), selectStatementBuilder, readerCollector);
    }
    readerCollector.add(new CollectionReferenceInitializerImpl(fetch, aliases));
}
Also used : OuterJoinLoadable(org.hibernate.persister.entity.OuterJoinLoadable) Joinable(org.hibernate.persister.entity.Joinable) EntityReferenceInitializerImpl(org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl) EntityReference(org.hibernate.loader.plan.spi.EntityReference) CollectionReferenceAliases(org.hibernate.loader.plan.exec.spi.CollectionReferenceAliases) QueryableCollection(org.hibernate.persister.collection.QueryableCollection) CollectionReferenceInitializerImpl(org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl)

Example 2 with CollectionReferenceAliases

use of org.hibernate.loader.plan.exec.spi.CollectionReferenceAliases in project hibernate-orm by hibernate.

the class AliasResolutionContextImpl method generateCollectionReferenceAliases.

/**
 * Generate the collection reference aliases for a particular {@link org.hibernate.loader.plan.spi.CollectionReference}
 * and register the generated value using the query space UID.
 * <p/>
 * Once generated, there are two methods that can be used to do look ups by the specified
 * query space UID:
 * <ul>
 * <li>
 *     {@link ##resolveCollectionReferenceAliases(String)} can be used to
 *     look up the returned collection reference aliases;
 * </li>
 * <li>
 *     {@link #resolveSqlTableAliasFromQuerySpaceUid(String)} can be used to
 *     look up the SQL collection table alias.
 * </li>
 * </ul>
 *
 * @param collectionQuerySpaceUid The query space UID for the collection reference.
 * @param persister The collection persister for collection reference.
 * @param elementQuerySpaceUid The query space UID for the collection element if
 *                             the element is an entity type; null, otherwise.
 * @return the generated collection reference aliases.
 * @throws IllegalArgumentException if the collection element is an entity type and
 *         {@code elementQuerySpaceUid} is null.
 *
 * @see org.hibernate.loader.plan.spi.CollectionReference#getQuerySpaceUid()
 * @see org.hibernate.loader.plan.spi.CollectionReference#getCollectionPersister()
 */
public CollectionReferenceAliases generateCollectionReferenceAliases(String collectionQuerySpaceUid, CollectionPersister persister, String elementQuerySpaceUid) {
    if (persister.getElementType().isEntityType() && elementQuerySpaceUid == null) {
        throw new IllegalArgumentException("elementQuerySpaceUid must be non-null for one-to-many or many-to-many associations.");
    }
    final String manyToManyTableAlias;
    final String tableAlias;
    if (persister.isManyToMany()) {
        manyToManyTableAlias = createTableAlias(persister.getRole());
        tableAlias = createTableAlias(persister.getElementDefinition().toEntityDefinition().getEntityPersister());
    } else {
        manyToManyTableAlias = null;
        tableAlias = createTableAlias(persister.getRole());
    }
    final CollectionReferenceAliases collectionAliases = new CollectionReferenceAliasesImpl(tableAlias, manyToManyTableAlias, createCollectionAliases(persister), createCollectionElementAliases(persister, tableAlias, elementQuerySpaceUid));
    registerQuerySpaceAliases(collectionQuerySpaceUid, collectionAliases);
    return collectionAliases;
}
Also used : CollectionReferenceAliases(org.hibernate.loader.plan.exec.spi.CollectionReferenceAliases)

Example 3 with CollectionReferenceAliases

use of org.hibernate.loader.plan.exec.spi.CollectionReferenceAliases in project hibernate-orm by hibernate.

the class AliasResolutionContextImpl method generateDetailLines.

private void generateDetailLines(QuerySpace querySpace, int depth, PrintWriter printWriter) {
    printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth) + querySpace.getUid() + " -> " + extractDetails(querySpace));
    printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + 3) + "SQL table alias mapping - " + resolveSqlTableAliasFromQuerySpaceUid(querySpace.getUid()));
    final EntityReferenceAliases entityAliases = resolveEntityReferenceAliases(querySpace.getUid());
    final CollectionReferenceAliases collectionReferenceAliases = resolveCollectionReferenceAliases(querySpace.getUid());
    if (entityAliases != null) {
        printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + 3) + "alias suffix - " + entityAliases.getColumnAliases().getSuffix());
        printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + 3) + "suffixed key columns - " + String.join(", ", entityAliases.getColumnAliases().getSuffixedKeyAliases()));
    }
    if (collectionReferenceAliases != null) {
        printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + 3) + "alias suffix - " + collectionReferenceAliases.getCollectionColumnAliases().getSuffix());
        printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + 3) + "suffixed key columns - " + String.join(", ", collectionReferenceAliases.getCollectionColumnAliases().getSuffixedKeyAliases()));
        final EntityReferenceAliases elementAliases = collectionReferenceAliases.getEntityElementAliases();
        if (elementAliases != null) {
            printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + 3) + "entity-element alias suffix - " + elementAliases.getColumnAliases().getSuffix());
            printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + 3) + elementAliases.getColumnAliases().getSuffix() + "entity-element suffixed key columns - " + String.join(", ", elementAliases.getColumnAliases().getSuffixedKeyAliases()));
        }
    }
}
Also used : EntityReferenceAliases(org.hibernate.loader.plan.exec.spi.EntityReferenceAliases) CollectionReferenceAliases(org.hibernate.loader.plan.exec.spi.CollectionReferenceAliases)

Example 4 with CollectionReferenceAliases

use of org.hibernate.loader.plan.exec.spi.CollectionReferenceAliases in project hibernate-orm by hibernate.

the class QuerySpaceTreePrinter method generateDetailLines.

private void generateDetailLines(QuerySpace querySpace, int depth, AliasResolutionContext aliasResolutionContext, PrintWriter printWriter) {
    printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth) + extractDetails(querySpace));
    if (aliasResolutionContext == null) {
        return;
    }
    printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + detailDepthOffset) + "SQL table alias mapping - " + aliasResolutionContext.resolveSqlTableAliasFromQuerySpaceUid(querySpace.getUid()));
    final EntityReferenceAliases entityAliases = aliasResolutionContext.resolveEntityReferenceAliases(querySpace.getUid());
    final CollectionReferenceAliases collectionReferenceAliases = aliasResolutionContext.resolveCollectionReferenceAliases(querySpace.getUid());
    if (entityAliases != null) {
        printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + detailDepthOffset) + "alias suffix - " + entityAliases.getColumnAliases().getSuffix());
        printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + detailDepthOffset) + "suffixed key columns - {" + String.join(", ", entityAliases.getColumnAliases().getSuffixedKeyAliases()) + "}");
    }
    if (collectionReferenceAliases != null) {
        printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + detailDepthOffset) + "alias suffix - " + collectionReferenceAliases.getCollectionColumnAliases().getSuffix());
        printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + detailDepthOffset) + "suffixed key columns - {" + String.join(", ", collectionReferenceAliases.getCollectionColumnAliases().getSuffixedKeyAliases()) + "}");
        final EntityAliases elementAliases = collectionReferenceAliases.getEntityElementAliases() == null ? null : collectionReferenceAliases.getEntityElementAliases().getColumnAliases();
        if (elementAliases != null) {
            printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + detailDepthOffset) + "entity-element alias suffix - " + elementAliases.getSuffix());
            printWriter.println(TreePrinterHelper.INSTANCE.generateNodePrefix(depth + detailDepthOffset) + elementAliases.getSuffix() + "entity-element suffixed key columns - " + String.join(", ", elementAliases.getSuffixedKeyAliases()));
        }
    }
}
Also used : EntityReferenceAliases(org.hibernate.loader.plan.exec.spi.EntityReferenceAliases) EntityAliases(org.hibernate.loader.EntityAliases) CollectionReferenceAliases(org.hibernate.loader.plan.exec.spi.CollectionReferenceAliases)

Aggregations

CollectionReferenceAliases (org.hibernate.loader.plan.exec.spi.CollectionReferenceAliases)4 EntityReferenceAliases (org.hibernate.loader.plan.exec.spi.EntityReferenceAliases)2 EntityAliases (org.hibernate.loader.EntityAliases)1 CollectionReferenceInitializerImpl (org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl)1 EntityReferenceInitializerImpl (org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl)1 EntityReference (org.hibernate.loader.plan.spi.EntityReference)1 QueryableCollection (org.hibernate.persister.collection.QueryableCollection)1 Joinable (org.hibernate.persister.entity.Joinable)1 OuterJoinLoadable (org.hibernate.persister.entity.OuterJoinLoadable)1