Search in sources :

Example 1 with FetchSource

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

the class AbstractLoadPlanBuildingAssociationVisitationStrategy method foundCircularAssociation.

@Override
public void foundCircularAssociation(AssociationAttributeDefinition attributeDefinition) {
    final FetchStrategy fetchStrategy = determineFetchStrategy(attributeDefinition);
    if (fetchStrategy.getStyle() != FetchStyle.JOIN) {
        // nothing to do
        return;
    }
    final AssociationKey associationKey = attributeDefinition.getAssociationKey();
    // go ahead and build the bidirectional fetch
    if (attributeDefinition.getAssociationNature() == AssociationAttributeDefinition.AssociationNature.ENTITY) {
        final Joinable currentEntityPersister = (Joinable) currentSource().resolveEntityReference().getEntityPersister();
        final AssociationKey currentEntityReferenceAssociationKey = new AssociationKey(currentEntityPersister.getTableName(), currentEntityPersister.getKeyColumnNames());
        // if associationKey is equal to currentEntityReferenceAssociationKey
        // that means that the current EntityPersister has a single primary key attribute
        // (i.e., derived attribute) which is mapped by attributeDefinition.
        // This is not a bidirectional association.
        // TODO: AFAICT, to avoid an overflow, the associated entity must already be loaded into the session, or
        // it must be loaded when the ID for the dependent entity is resolved. Is there some other way to
        // deal with this???
        final FetchSource registeredFetchSource = registeredFetchSource(associationKey);
        if (registeredFetchSource != null && !associationKey.equals(currentEntityReferenceAssociationKey)) {
            currentSource().buildBidirectionalEntityReference(attributeDefinition, fetchStrategy, registeredFetchSource(associationKey).resolveEntityReference());
        }
    } else {
    // Do nothing for collection
    }
}
Also used : AssociationKey(org.hibernate.persister.walking.spi.AssociationKey) FetchSource(org.hibernate.loader.plan.spi.FetchSource) ExpandingFetchSource(org.hibernate.loader.plan.build.spi.ExpandingFetchSource) FetchStrategy(org.hibernate.engine.FetchStrategy) Joinable(org.hibernate.persister.entity.Joinable)

Example 2 with FetchSource

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

the class AbstractLoadPlanBuildingAssociationVisitationStrategy method finishingEntity.

@Override
public void finishingEntity(EntityDefinition entityDefinition) {
    // Only process the entityDefinition if it is for the root return.
    final FetchSource currentSource = currentSource();
    final boolean isRoot = EntityReturn.class.isInstance(currentSource) && entityDefinition.getEntityPersister().equals(EntityReturn.class.cast(currentSource).getEntityPersister());
    if (!isRoot) {
        // if not, this call should represent a fetch which will be handled in #finishingAttribute
        return;
    }
    // if we get here, it is a root
    final ExpandingFetchSource popped = popFromStack();
    checkPoppedEntity(popped, entityDefinition);
    log.tracef("%s Finished root entity : %s", StringHelper.repeat("<<", fetchSourceStack.size()), entityDefinition.getEntityPersister().getEntityName());
}
Also used : FetchSource(org.hibernate.loader.plan.spi.FetchSource) ExpandingFetchSource(org.hibernate.loader.plan.build.spi.ExpandingFetchSource) ExpandingFetchSource(org.hibernate.loader.plan.build.spi.ExpandingFetchSource) EntityReturn(org.hibernate.loader.plan.spi.EntityReturn)

Example 3 with FetchSource

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

the class LoadQueryJoinAndFetchProcessor method processFetches.

public FetchStats processFetches(FetchSource fetchSource, SelectStatementBuilder selectStatementBuilder, ReaderCollector readerCollector) {
    final FetchStatsImpl fetchStats = new FetchStatsImpl();
    // what if fetchSource is a composite fetch (as it would be in the case of a key-many-to-one)?
    if (EntityReference.class.isInstance(fetchSource)) {
        final EntityReference fetchOwnerAsEntityReference = (EntityReference) fetchSource;
        if (fetchOwnerAsEntityReference.getIdentifierDescription().hasFetches()) {
            final FetchSource entityIdentifierAsFetchSource = (FetchSource) fetchOwnerAsEntityReference.getIdentifierDescription();
            for (Fetch fetch : entityIdentifierAsFetchSource.getFetches()) {
                processFetch(selectStatementBuilder, fetchSource, fetch, readerCollector, fetchStats);
            }
        }
    }
    processFetches(fetchSource, selectStatementBuilder, readerCollector, fetchStats);
    return 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) EntityReference(org.hibernate.loader.plan.spi.EntityReference)

Example 4 with FetchSource

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

the class LoadQueryJoinAndFetchProcessor method processFetch.

private void processFetch(SelectStatementBuilder selectStatementBuilder, FetchSource fetchSource, Fetch fetch, ReaderCollector readerCollector, FetchStatsImpl fetchStats) {
    // process fetch even if it is not join fetched
    if (EntityFetch.class.isInstance(fetch)) {
        final EntityFetch entityFetch = (EntityFetch) fetch;
        processEntityFetch(selectStatementBuilder, fetchSource, entityFetch, readerCollector, fetchStats);
    } else if (CollectionAttributeFetch.class.isInstance(fetch)) {
        final CollectionAttributeFetch collectionFetch = (CollectionAttributeFetch) fetch;
        processCollectionFetch(selectStatementBuilder, fetchSource, collectionFetch, readerCollector, fetchStats);
    } else {
        // but do still need to visit their fetches...
        if (FetchSource.class.isInstance(fetch)) {
            processFetches((FetchSource) fetch, selectStatementBuilder, readerCollector, fetchStats);
        }
    }
}
Also used : EntityFetch(org.hibernate.loader.plan.spi.EntityFetch) CollectionAttributeFetch(org.hibernate.loader.plan.spi.CollectionAttributeFetch) FetchSource(org.hibernate.loader.plan.spi.FetchSource)

Example 5 with FetchSource

use of org.hibernate.loader.plan.spi.FetchSource 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)

Aggregations

FetchSource (org.hibernate.loader.plan.spi.FetchSource)8 CollectionAttributeFetch (org.hibernate.loader.plan.spi.CollectionAttributeFetch)5 EntityFetch (org.hibernate.loader.plan.spi.EntityFetch)4 ExpandingFetchSource (org.hibernate.loader.plan.build.spi.ExpandingFetchSource)3 EntityReturn (org.hibernate.loader.plan.spi.EntityReturn)2 Fetch (org.hibernate.loader.plan.spi.Fetch)2 Joinable (org.hibernate.persister.entity.Joinable)2 ArrayList (java.util.ArrayList)1 HibernateException (org.hibernate.HibernateException)1 Configuration (org.hibernate.cfg.Configuration)1 FetchStrategy (org.hibernate.engine.FetchStrategy)1 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)1 MultipleBagFetchException (org.hibernate.loader.MultipleBagFetchException)1 CollectionFetchableElementEntityGraph (org.hibernate.loader.plan.build.internal.returns.CollectionFetchableElementEntityGraph)1 EntityReferenceInitializerImpl (org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl)1 ResultSetProcessorImpl (org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl)1 SelectStatementBuilder (org.hibernate.loader.plan.exec.query.internal.SelectStatementBuilder)1 EntityReferenceAliases (org.hibernate.loader.plan.exec.spi.EntityReferenceAliases)1 BidirectionalEntityReference (org.hibernate.loader.plan.spi.BidirectionalEntityReference)1 CollectionFetchableIndex (org.hibernate.loader.plan.spi.CollectionFetchableIndex)1