Search in sources :

Example 1 with EntityReferenceInitializerImpl

use of org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl in project hibernate-orm by hibernate.

the class LoadQueryJoinAndFetchProcessor method processEntityFetch.

private void processEntityFetch(SelectStatementBuilder selectStatementBuilder, FetchSource fetchSource, EntityFetch fetch, ReaderCollector readerCollector, FetchStatsImpl fetchStats) {
    // todo : still need to think through expressing bi-directionality in the new model...
    //		if ( BidirectionalEntityFetch.class.isInstance( fetch ) ) {
    //			log.tracef( "Skipping bi-directional entity fetch [%s]", fetch );
    //			return;
    //		}
    fetchStats.processingFetch(fetch);
    if (!FetchStrategyHelper.isJoinFetched(fetch.getFetchStrategy())) {
        // not join fetched, so nothing else to do
        return;
    }
    // First write out the SQL SELECT fragments
    final Joinable joinable = (Joinable) fetch.getEntityPersister();
    EntityReferenceAliases aliases = aliasResolutionContext.resolveEntityReferenceAliases(fetch.getQuerySpaceUid());
    // the null arguments here relate to many-to-many fetches
    selectStatementBuilder.appendSelectClauseFragment(joinable.selectFragment(null, null, aliases.getTableAlias(), aliases.getColumnAliases().getSuffix(), null, true));
    // process its identifier fetches first (building EntityReferenceInitializers for them if needed)
    if (fetch.getIdentifierDescription().hasFetches()) {
        final FetchSource entityIdentifierAsFetchSource = (FetchSource) fetch.getIdentifierDescription();
        for (Fetch identifierFetch : entityIdentifierAsFetchSource.getFetches()) {
            processFetch(selectStatementBuilder, fetch, identifierFetch, readerCollector, fetchStats);
        }
    }
    // build an EntityReferenceInitializers for the incoming fetch itself
    readerCollector.add(new EntityReferenceInitializerImpl(fetch, aliases));
    // then visit each of our (non-identifier) fetches
    processFetches(fetch, selectStatementBuilder, readerCollector, fetchStats);
}
Also used : Fetch(org.hibernate.loader.plan.spi.Fetch) EntityFetch(org.hibernate.loader.plan.spi.EntityFetch) CollectionAttributeFetch(org.hibernate.loader.plan.spi.CollectionAttributeFetch) FetchSource(org.hibernate.loader.plan.spi.FetchSource) EntityReferenceAliases(org.hibernate.loader.plan.exec.spi.EntityReferenceAliases) Joinable(org.hibernate.persister.entity.Joinable) EntityReferenceInitializerImpl(org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl)

Example 2 with EntityReferenceInitializerImpl

use of org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl 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)

Aggregations

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