use of org.hibernate.loader.plan.spi.CollectionAttributeFetch in project hibernate-orm by hibernate.
the class AbstractExpandingFetchSource method buildCollectionAttributeFetch.
@Override
public CollectionAttributeFetch buildCollectionAttributeFetch(AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy) {
final ExpandingCollectionQuerySpace collectionQuerySpace = QuerySpaceHelper.INSTANCE.makeCollectionQuerySpace(querySpace, attributeDefinition, getQuerySpaces().generateImplicitUid(), fetchStrategy);
final CollectionAttributeFetch fetch = new CollectionAttributeFetchImpl(this, attributeDefinition, fetchStrategy, collectionQuerySpace);
addFetch(fetch);
return fetch;
}
use of org.hibernate.loader.plan.spi.CollectionAttributeFetch 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);
}
}
}
use of org.hibernate.loader.plan.spi.CollectionAttributeFetch in project hibernate-orm by hibernate.
the class ReturnGraphTreePrinter method writeFetch.
private void writeFetch(Fetch fetch, int depth, PrintWriter printWriter) {
printWriter.print(TreePrinterHelper.INSTANCE.generateNodePrefix(depth));
if (EntityFetch.class.isInstance(fetch)) {
final EntityFetch entityFetch = (EntityFetch) fetch;
printWriter.println(extractDetails(entityFetch));
writeEntityReferenceFetches(entityFetch, depth + 1, printWriter);
} else if (CompositeFetch.class.isInstance(fetch)) {
final CompositeFetch compositeFetch = (CompositeFetch) fetch;
printWriter.println(extractDetails(compositeFetch));
writeCompositeFetchFetches(compositeFetch, depth + 1, printWriter);
} else if (CollectionAttributeFetch.class.isInstance(fetch)) {
final CollectionAttributeFetch collectionFetch = (CollectionAttributeFetch) fetch;
printWriter.println(extractDetails(collectionFetch));
writeCollectionReferenceFetches(collectionFetch, depth + 1, printWriter);
}
}
use of org.hibernate.loader.plan.spi.CollectionAttributeFetch in project hibernate-orm by hibernate.
the class LoadPlanStructureAssertionTest method testEncapsulatedCompositeIdWithFetches2.
@Test
public void testEncapsulatedCompositeIdWithFetches2() {
Configuration cfg = new Configuration();
cfg.addAnnotatedClass(Card.class);
cfg.addAnnotatedClass(CardField.class);
cfg.addAnnotatedClass(Key.class);
cfg.addAnnotatedClass(PrimaryKey.class);
final SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
try {
final OuterJoinLoadable cardPersister = (OuterJoinLoadable) sf.getClassMetadata(Card.class);
doCompare(sf, cardPersister);
final LoadPlan cardLoadPlan = LoadPlanStructureAssertionHelper.INSTANCE.buildLoadPlan(sf, cardPersister);
assertEquals(LoadPlan.Disposition.ENTITY_LOADER, cardLoadPlan.getDisposition());
assertEquals(1, cardLoadPlan.getReturns().size());
// Check the root EntityReturn(Card)
final EntityReturn cardReturn = assertTyping(EntityReturn.class, cardLoadPlan.getReturns().get(0));
assertFalse(cardReturn.getIdentifierDescription().hasFetches());
// Card should have one fetch, the fields collection
assertEquals(1, cardReturn.getFetches().length);
final CollectionAttributeFetch fieldsFetch = assertTyping(CollectionAttributeFetch.class, cardReturn.getFetches()[0]);
assertNotNull(fieldsFetch.getElementGraph());
// the Card.fields collection has entity elements of type CardField...
final CollectionFetchableElementEntityGraph cardFieldElementGraph = assertTyping(CollectionFetchableElementEntityGraph.class, fieldsFetch.getElementGraph());
// CardField should have no fetches
assertEquals(0, cardFieldElementGraph.getFetches().length);
// But it should have 1 key-many-to-one fetch for Key (Card is already handled)
assertTrue(cardFieldElementGraph.getIdentifierDescription().hasFetches());
final FetchSource cardFieldElementGraphIdAsFetchSource = assertTyping(FetchSource.class, cardFieldElementGraph.getIdentifierDescription());
assertEquals(1, cardFieldElementGraphIdAsFetchSource.getFetches().length);
assertEquals(1, cardFieldElementGraphIdAsFetchSource.getBidirectionalEntityReferences().length);
BidirectionalEntityReference circularCardFetch = assertTyping(BidirectionalEntityReference.class, cardFieldElementGraphIdAsFetchSource.getBidirectionalEntityReferences()[0]);
assertSame(circularCardFetch.getTargetEntityReference(), cardReturn);
// the fetch above is to the other key-many-to-one for CardField.primaryKey composite: key
EntityFetch keyFetch = assertTyping(EntityFetch.class, cardFieldElementGraphIdAsFetchSource.getFetches()[0]);
assertEquals(Key.class.getName(), keyFetch.getEntityPersister().getEntityName());
} finally {
sf.close();
}
}
use of org.hibernate.loader.plan.spi.CollectionAttributeFetch in project hibernate-orm by hibernate.
the class AbstractLoadQueryDetails method generate.
/**
* Main entry point for properly handling the FROM clause and and joins and restrictions
*/
protected void generate() {
// There are 2 high-level requirements to perform here:
// 1) Determine the SQL required to carry out the given LoadPlan (and fulfill
// {@code LoadQueryDetails#getSqlStatement()}). SelectStatementBuilder collects the ongoing efforts to
// build the needed SQL.
// 2) Determine how to read information out of the ResultSet resulting from executing the indicated SQL
// (the SQL aliases). ReaderCollector and friends are where this work happens, ultimately
// producing a ResultSetProcessor
final SelectStatementBuilder select = new SelectStatementBuilder(queryProcessor.getSessionFactory().getDialect());
// LoadPlan is broken down into 2 high-level pieces that we need to process here.
//
// First is the QuerySpaces, which roughly equates to the SQL FROM-clause. We'll cycle through
// those first, generating aliases into the AliasContext in addition to writing SQL FROM-clause information
// into SelectStatementBuilder. The AliasContext is populated here and the reused while process the SQL
// SELECT-clause into the SelectStatementBuilder and then again also to build the ResultSetProcessor
applyRootReturnTableFragments(select);
if (shouldApplyRootReturnFilterBeforeKeyRestriction()) {
applyRootReturnFilterRestrictions(select);
// add restrictions...
// first, the load key restrictions (which entity(s)/collection(s) do we want to load?)
applyKeyRestriction(select, getRootTableAlias(), keyColumnNames, getQueryBuildingParameters().getBatchSize());
} else {
// add restrictions...
// first, the load key restrictions (which entity(s)/collection(s) do we want to load?)
applyKeyRestriction(select, getRootTableAlias(), keyColumnNames, getQueryBuildingParameters().getBatchSize());
applyRootReturnFilterRestrictions(select);
}
applyRootReturnWhereJoinRestrictions(select);
applyRootReturnOrderByFragments(select);
// then move on to joins...
applyRootReturnSelectFragments(select);
queryProcessor.processQuerySpaceJoins(getRootQuerySpace(), select);
// Next, we process the Returns and Fetches building the SELECT clause and at the same time building
// Readers for reading the described results out of a SQL ResultSet
FetchStats fetchStats = null;
if (FetchSource.class.isInstance(rootReturn)) {
fetchStats = queryProcessor.processFetches((FetchSource) rootReturn, select, getReaderCollector());
} else if (CollectionReturn.class.isInstance(rootReturn)) {
final CollectionReturn collectionReturn = (CollectionReturn) rootReturn;
if (collectionReturn.getElementGraph() != null) {
fetchStats = queryProcessor.processFetches(collectionReturn.getElementGraph(), select, getReaderCollector());
}
// TODO: what about index???
}
if (fetchStats != null && fetchStats.getJoinedBagAttributeFetches().size() > 1) {
final List<String> bagRoles = new ArrayList<>();
for (CollectionAttributeFetch bagFetch : fetchStats.getJoinedBagAttributeFetches()) {
bagRoles.add(bagFetch.getCollectionPersister().getRole());
}
throw new MultipleBagFetchException(bagRoles);
}
LoadPlanTreePrinter.INSTANCE.logTree(loadPlan, queryProcessor.getAliasResolutionContext());
this.sqlStatement = select.toStatementString();
this.resultSetProcessor = new ResultSetProcessorImpl(loadPlan, queryProcessor.getAliasResolutionContext(), getReaderCollector().buildRowReader(), shouldUseOptionalEntityInstance(), isSubselectLoadingEnabled(fetchStats));
}
Aggregations