Search in sources :

Example 1 with EntityReference

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

the class AbstractLoadPlanBuildingAssociationVisitationStrategy method finishingEntityIdentifier.

@Override
public void finishingEntityIdentifier(EntityIdentifierDefinition entityIdentifierDefinition) {
    // only pop from stack if the current source is ExpandingEntityIdentifierDescription..
    final ExpandingFetchSource currentSource = currentSource();
    if (!ExpandingEntityIdentifierDescription.class.isInstance(currentSource)) {
        // in this case, the current source should be the entity that owns entityIdentifierDefinition
        if (!EntityReference.class.isInstance(currentSource)) {
            throw new WalkingException("Unexpected state in FetchSource stack");
        }
        final EntityReference entityReference = (EntityReference) currentSource;
        if (entityReference.getEntityPersister().getEntityKeyDefinition() != entityIdentifierDefinition) {
            throw new WalkingException(String.format("Encountered unexpected fetch owner [%s] in stack while processing entity identifier for [%s]", entityReference.getEntityPersister().getEntityName(), entityIdentifierDefinition.getEntityDefinition().getEntityPersister().getEntityName()));
        }
        return;
    }
    // the current source is ExpandingEntityIdentifierDescription...
    final ExpandingEntityIdentifierDescription identifierDescription = (ExpandingEntityIdentifierDescription) popFromStack();
    // and then on the node beforeQuery it (which should be the entity that owns the identifier being described)
    final ExpandingFetchSource entitySource = currentSource();
    if (!EntityReference.class.isInstance(entitySource)) {
        throw new WalkingException("Unexpected state in FetchSource stack");
    }
    final EntityReference entityReference = (EntityReference) entitySource;
    if (entityReference.getIdentifierDescription() != identifierDescription) {
        throw new WalkingException(String.format("Encountered unexpected fetch owner [%s] in stack while processing entity identifier for [%s]", entityReference.getEntityPersister().getEntityName(), entityIdentifierDefinition.getEntityDefinition().getEntityPersister().getEntityName()));
    }
    log.tracef("%s Finished entity identifier : %s", StringHelper.repeat("<<", fetchSourceStack.size()), entityIdentifierDefinition.getEntityDefinition().getEntityPersister().getEntityName());
}
Also used : ExpandingEntityIdentifierDescription(org.hibernate.loader.plan.build.spi.ExpandingEntityIdentifierDescription) EntityReference(org.hibernate.loader.plan.spi.EntityReference) ExpandingFetchSource(org.hibernate.loader.plan.build.spi.ExpandingFetchSource) WalkingException(org.hibernate.persister.walking.spi.WalkingException)

Example 2 with EntityReference

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

the class ReturnGraphTreePrinter method writeCollectionReferenceFetches.

private void writeCollectionReferenceFetches(CollectionReference collectionReference, int depth, PrintWriter printWriter) {
    final CollectionFetchableIndex indexGraph = collectionReference.getIndexGraph();
    if (indexGraph != null) {
        printWriter.print(TreePrinterHelper.INSTANCE.generateNodePrefix(depth) + "(collection index) ");
        if (EntityReference.class.isInstance(indexGraph)) {
            final EntityReference indexGraphAsEntityReference = (EntityReference) indexGraph;
            printWriter.println(extractDetails(indexGraphAsEntityReference));
            writeEntityReferenceFetches(indexGraphAsEntityReference, depth + 1, printWriter);
        } else if (CompositeFetch.class.isInstance(indexGraph)) {
            final CompositeFetch indexGraphAsCompositeFetch = (CompositeFetch) indexGraph;
            printWriter.println(extractDetails(indexGraphAsCompositeFetch));
            writeCompositeFetchFetches(indexGraphAsCompositeFetch, depth + 1, printWriter);
        }
    }
    final CollectionFetchableElement elementGraph = collectionReference.getElementGraph();
    if (elementGraph != null) {
        printWriter.print(TreePrinterHelper.INSTANCE.generateNodePrefix(depth) + "(collection element) ");
        if (EntityReference.class.isInstance(elementGraph)) {
            final EntityReference elementGraphAsEntityReference = (EntityReference) elementGraph;
            printWriter.println(extractDetails(elementGraphAsEntityReference));
            writeEntityReferenceFetches(elementGraphAsEntityReference, depth + 1, printWriter);
        } else if (CompositeFetch.class.isInstance(elementGraph)) {
            final CompositeFetch elementGraphAsCompositeFetch = (CompositeFetch) elementGraph;
            printWriter.println(extractDetails(elementGraphAsCompositeFetch));
            writeCompositeFetchFetches(elementGraphAsCompositeFetch, depth + 1, printWriter);
        }
    }
}
Also used : CollectionFetchableElement(org.hibernate.loader.plan.spi.CollectionFetchableElement) CompositeFetch(org.hibernate.loader.plan.spi.CompositeFetch) EntityReference(org.hibernate.loader.plan.spi.EntityReference) BidirectionalEntityReference(org.hibernate.loader.plan.spi.BidirectionalEntityReference) CollectionFetchableIndex(org.hibernate.loader.plan.spi.CollectionFetchableIndex)

Example 3 with EntityReference

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

the class AbstractCollectionLoadQueryDetails method applyRootReturnSelectFragments.

@Override
protected void applyRootReturnSelectFragments(SelectStatementBuilder selectStatementBuilder) {
    if (getRootCollectionReturn().allowIndexJoin() && getQueryableCollection().getIndexType().isEntityType()) {
        final EntityReference indexEntityReference = getRootCollectionReturn().getIndexGraph().resolveEntityReference();
        final EntityReferenceAliases indexEntityReferenceAliases = getAliasResolutionContext().resolveEntityReferenceAliases(indexEntityReference.getQuerySpaceUid());
        selectStatementBuilder.appendSelectClauseFragment(((OuterJoinLoadable) indexEntityReference.getEntityPersister()).selectFragment(indexEntityReferenceAliases.getTableAlias(), indexEntityReferenceAliases.getColumnAliases().getSuffix()));
    }
}
Also used : EntityReferenceAliases(org.hibernate.loader.plan.exec.spi.EntityReferenceAliases) EntityReference(org.hibernate.loader.plan.spi.EntityReference)

Example 4 with EntityReference

use of org.hibernate.loader.plan.spi.EntityReference 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 5 with EntityReference

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

EntityReference (org.hibernate.loader.plan.spi.EntityReference)10 EntityKey (org.hibernate.engine.spi.EntityKey)2 BidirectionalEntityReference (org.hibernate.loader.plan.spi.BidirectionalEntityReference)2 EntityFetch (org.hibernate.loader.plan.spi.EntityFetch)2 WalkingException (org.hibernate.persister.walking.spi.WalkingException)2 ResultSet (java.sql.ResultSet)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 IdentityHashMap (java.util.IdentityHashMap)1 Map (java.util.Map)1 Set (java.util.Set)1 SubselectFetch (org.hibernate.engine.spi.SubselectFetch)1 FetchStyleLoadPlanBuildingAssociationVisitationStrategy (org.hibernate.loader.plan.build.internal.FetchStyleLoadPlanBuildingAssociationVisitationStrategy)1 ExpandingEntityIdentifierDescription (org.hibernate.loader.plan.build.spi.ExpandingEntityIdentifierDescription)1 ExpandingFetchSource (org.hibernate.loader.plan.build.spi.ExpandingFetchSource)1 AliasResolutionContextImpl (org.hibernate.loader.plan.exec.internal.AliasResolutionContextImpl)1 CollectionReferenceInitializerImpl (org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl)1 EntityReferenceInitializerImpl (org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl)1 CollectionReferenceAliases (org.hibernate.loader.plan.exec.spi.CollectionReferenceAliases)1 EntityReferenceAliases (org.hibernate.loader.plan.exec.spi.EntityReferenceAliases)1