Skip to content

Commit aaadcd7

Browse files
stliusebersole
authored andcommitted
HHH-8276 - Integrate LoadPlans into UniqueEntityLoader (PoC)
1 parent c5f3dde commit aaadcd7

File tree

5 files changed

+94
-93
lines changed

5 files changed

+94
-93
lines changed

hibernate-core/src/main/java/org/hibernate/loader/plan2/build/spi/LoadPlanTreePrinter.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ public void logTree(LoadPlan loadPlan, AliasResolutionContextImpl aliasResolutio
8484
printWriter.flush();
8585
printStream.flush();
8686
log.debug( new String( byteArrayOutputStream.toByteArray() ) );
87-
88-
// log.debug( toString( loadPlan, aliasResolutionContext ) );
8987
}
9088

9189
private void logTree(

hibernate-core/src/main/java/org/hibernate/loader/plan2/exec/internal/AliasResolutionContextImpl.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public class AliasResolutionContextImpl implements AliasResolutionContext {
6969

7070
private Map<String,EntityReferenceAliases> entityReferenceAliasesMap;
7171
private Map<String,CollectionReferenceAliases> collectionReferenceAliasesMap;
72-
private Map<String, String> querySpaceUidToSqlTableAliasMap;
72+
private Map<String,String> querySpaceUidToSqlTableAliasMap;
7373

7474
private Map<String,String> compositeQuerySpaceUidToSqlTableAliasMap;
7575

@@ -129,11 +129,11 @@ private String createSuffix() {
129129
}
130130

131131
public CollectionReferenceAliases generateCollectionReferenceAliases(String uid, CollectionPersister persister) {
132+
final String manyToManyTableAlias = persister.isManyToMany()? createTableAlias( persister.getRole() ) : null;
133+
final String tableAlias = createTableAlias( persister.getRole() );
132134
final CollectionReferenceAliasesImpl aliases = new CollectionReferenceAliasesImpl(
133-
createTableAlias( persister.getRole() ),
134-
persister.isManyToMany()
135-
? createTableAlias( persister.getRole() )
136-
: null,
135+
tableAlias,
136+
manyToManyTableAlias,
137137
createCollectionAliases( persister ),
138138
createCollectionElementAliases( persister )
139139
);
@@ -212,7 +212,7 @@ public void registerQuerySpaceAliases(String querySpaceUid, CollectionReferenceA
212212
collectionReferenceAliasesMap = new HashMap<String, CollectionReferenceAliases>();
213213
}
214214
collectionReferenceAliasesMap.put( querySpaceUid, collectionReferenceAliases );
215-
registerSqlTableAliasMapping( querySpaceUid, collectionReferenceAliases.getElementTableAlias() );
215+
registerSqlTableAliasMapping( querySpaceUid, collectionReferenceAliases.getCollectionTableAlias() );
216216
}
217217

218218
@Override

hibernate-core/src/main/java/org/hibernate/loader/plan2/exec/internal/LoadQueryJoinAndFetchProcessor.java

Lines changed: 81 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
* @author Steve Ebersole
6969
*/
7070
public class LoadQueryJoinAndFetchProcessor {
71-
private static final Logger log = CoreLogging.logger( LoadQueryJoinAndFetchProcessor.class );
71+
private static final Logger LOG = CoreLogging.logger( LoadQueryJoinAndFetchProcessor.class );
7272

7373
private final AliasResolutionContextImpl aliasResolutionContext;
7474
private final QueryBuildingParameters buildingParameters;
@@ -91,6 +91,7 @@ public LoadQueryJoinAndFetchProcessor(
9191
}
9292

9393
public void processQuerySpaceJoins(QuerySpace querySpace, SelectStatementBuilder selectStatementBuilder) {
94+
LOG.debug( "processing queryspace " + querySpace.getUid() );
9495
final JoinFragment joinFragment = factory.getDialect().createOuterJoinFragment();
9596
processQuerySpaceJoins( querySpace, joinFragment );
9697

@@ -127,7 +128,16 @@ private void renderJoin(Join join, JoinFragment joinFragment) {
127128
else if ( EntityQuerySpace.class.isInstance( join.getRightHandSide() ) ) {
128129
// do not render the entity join for a one-to-many association, since the collection join
129130
// already joins to the associated entity table (see doc in renderCollectionJoin()).
130-
if ( join.getLeftHandSide().getDisposition() != QuerySpace.Disposition.COLLECTION ||
131+
if ( join.getLeftHandSide().getDisposition() == QuerySpace.Disposition.COLLECTION &&
132+
CollectionQuerySpace.class.cast( join.getLeftHandSide() ).getCollectionPersister().isManyToMany() ) {
133+
final CollectionQuerySpace leftHandSide = (CollectionQuerySpace) join.getLeftHandSide();
134+
final CollectionReferenceAliases aliases = aliasResolutionContext.resolveCollectionReferenceAliases(
135+
leftHandSide.getUid()
136+
);
137+
138+
renderManyToManyJoin(aliases, leftHandSide, join, joinFragment );
139+
}
140+
else if ( join.getLeftHandSide().getDisposition() != QuerySpace.Disposition.COLLECTION ||
131141
! CollectionQuerySpace.class.cast( join.getLeftHandSide() ).getCollectionPersister().isOneToMany() ) {
132142
renderEntityJoin( join, joinFragment );
133143
}
@@ -371,34 +381,34 @@ private void renderSqlJoinToCollectionTable(
371381
);
372382
}
373383

374-
// private void renderManyToManyJoin(
375-
// CollectionReferenceAliases aliases,
376-
// CollectionQuerySpace rightHandSide,
384+
private void renderManyToManyJoin(
385+
CollectionReferenceAliases aliases,
386+
CollectionQuerySpace rightHandSide,
377387
// String[] aliasedLhsColumnNames,
378-
// Join join,
379-
// JoinFragment joinFragment) {
380-
// final CollectionPersister persister = rightHandSide.getCollectionPersister();
381-
// final QueryableCollection queryableCollection = (QueryableCollection) persister;
382-
//
383-
// // for many-to-many we have 3 table aliases. By way of example, consider a normal m-n: User<->Role
384-
// // where User is the FetchOwner and Role (User.roles) is the Fetch. We'd have:
385-
// // 1) the owner's table : user - in terms of rendering the joins (not the fetch select fragments), the
386-
// // lhs table alias is only needed to qualify the lhs join columns, but we already have the qualified
387-
// // columns here (aliasedLhsColumnNames)
388-
// //final String ownerTableAlias = ...;
389-
// // 2) the m-n table : user_role
390-
// final String collectionTableAlias = aliases.getCollectionTableAlias();
391-
// // 3) the element table : role
392-
// final String elementTableAlias = aliases.getElementTableAlias();
393-
//
394-
// // somewhere, one of these being empty is causing trouble...
395-
// if ( StringHelper.isEmpty( collectionTableAlias ) ) {
396-
// throw new IllegalStateException( "Collection table alias cannot be empty" );
397-
// }
398-
// if ( StringHelper.isEmpty( elementTableAlias ) ) {
399-
// throw new IllegalStateException( "Collection element (many-to-many) table alias cannot be empty" );
400-
// }
401-
//
388+
Join join,
389+
JoinFragment joinFragment) {
390+
final CollectionPersister persister = rightHandSide.getCollectionPersister();
391+
final QueryableCollection queryableCollection = (QueryableCollection) persister;
392+
393+
// for many-to-many we have 3 table aliases. By way of example, consider a normal m-n: User<->Role
394+
// where User is the FetchOwner and Role (User.roles) is the Fetch. We'd have:
395+
// 1) the owner's table : user - in terms of rendering the joins (not the fetch select fragments), the
396+
// lhs table alias is only needed to qualify the lhs join columns, but we already have the qualified
397+
// columns here (aliasedLhsColumnNames)
398+
//final String ownerTableAlias = ...;
399+
// 2) the m-n table : user_role
400+
final String collectionTableAlias = aliases.getCollectionTableAlias();
401+
// 3) the element table : role
402+
final String elementTableAlias = aliases.getElementTableAlias();
403+
404+
// somewhere, one of these being empty is causing trouble...
405+
if ( StringHelper.isEmpty( collectionTableAlias ) ) {
406+
throw new IllegalStateException( "Collection table alias cannot be empty" );
407+
}
408+
if ( StringHelper.isEmpty( elementTableAlias ) ) {
409+
throw new IllegalStateException( "Collection element (many-to-many) table alias cannot be empty" );
410+
}
411+
402412
//
403413
// {
404414
// // add join fragments from the owner table -> collection table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -420,45 +430,45 @@ private void renderSqlJoinToCollectionTable(
420430
// queryableCollection.whereJoinFragment( collectionTableAlias, false, true )
421431
// );
422432
// }
423-
//
424-
// {
425-
// // add join fragments from the collection table -> element entity table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
426-
// final String additionalJoinConditions = resolveAdditionalJoinCondition(
427-
// elementTableAlias,
428-
// join.getAnyAdditionalJoinConditions( elementTableAlias ),
429-
// queryableCollection
430-
// );
431-
//
432-
// final String manyToManyFilter = persister.getManyToManyFilterFragment(
433-
// collectionTableAlias,
434-
// buildingParameters.getQueryInfluencers().getEnabledFilters()
435-
// );
436-
//
437-
// final String condition;
438-
// if ( StringHelper.isEmpty( manyToManyFilter ) ) {
439-
// condition = additionalJoinConditions;
440-
// }
441-
// else if ( StringHelper.isEmpty( additionalJoinConditions ) ) {
442-
// condition = manyToManyFilter;
443-
// }
444-
// else {
445-
// condition = additionalJoinConditions + " and " + manyToManyFilter;
446-
// }
447-
//
448-
// final OuterJoinLoadable elementPersister = (OuterJoinLoadable) queryableCollection.getElementPersister();
449-
//
450-
// addJoins(
451-
// joinFragment,
452-
// elementPersister,
453-
// JoinType.LEFT_OUTER_JOIN,
454-
// elementTableAlias,
455-
// elementPersister.getIdentifierColumnNames(),
456-
// StringHelper.qualify( collectionTableAlias, queryableCollection.getElementColumnNames() ),
457-
// condition
458-
// );
459-
// }
460-
// }
461-
//
433+
434+
{
435+
// add join fragments from the collection table -> element entity table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
436+
final String additionalJoinConditions = resolveAdditionalJoinCondition(
437+
elementTableAlias,
438+
join.getAnyAdditionalJoinConditions( elementTableAlias ),
439+
queryableCollection
440+
);
441+
442+
final String manyToManyFilter = persister.getManyToManyFilterFragment(
443+
collectionTableAlias,
444+
buildingParameters.getQueryInfluencers().getEnabledFilters()
445+
);
446+
447+
final String condition;
448+
if ( StringHelper.isEmpty( manyToManyFilter ) ) {
449+
condition = additionalJoinConditions;
450+
}
451+
else if ( StringHelper.isEmpty( additionalJoinConditions ) ) {
452+
condition = manyToManyFilter;
453+
}
454+
else {
455+
condition = additionalJoinConditions + " and " + manyToManyFilter;
456+
}
457+
458+
final OuterJoinLoadable elementPersister = (OuterJoinLoadable) queryableCollection.getElementPersister();
459+
460+
addJoins(
461+
joinFragment,
462+
elementPersister,
463+
JoinType.LEFT_OUTER_JOIN,
464+
elementTableAlias,
465+
elementPersister.getIdentifierColumnNames(),
466+
StringHelper.qualify( collectionTableAlias, queryableCollection.getElementColumnNames() ),
467+
condition
468+
);
469+
}
470+
}
471+
462472
// private void renderOneToManyJoin(
463473
// CollectionReferenceAliases aliases,
464474
// CollectionQuerySpace rightHandSide,
@@ -699,8 +709,9 @@ private void processCollectionFetch(
699709
selectStatementBuilder.appendSelectClauseFragment(
700710
joinableCollection.selectFragment(
701711
(Joinable) queryableCollection.getElementPersister(),
702-
ownerTableAlias,
712+
elementTableAlias,
703713
collectionTableAlias,
714+
704715
aliases.getEntityElementColumnAliases().getSuffix(),
705716
aliases.getCollectionColumnAliases().getSuffix(),
706717
true
@@ -731,7 +742,7 @@ private void processCollectionFetch(
731742
final EntityReferenceAliases entityReferenceAliases = new EntityReferenceAliases() {
732743
@Override
733744
public String getTableAlias() {
734-
return aliases.getElementTableAlias();
745+
return aliases.getCollectionTableAlias();
735746
}
736747

737748
@Override

hibernate-core/src/main/java/org/hibernate/loader/plan2/exec/process/internal/ResultSetProcessingContextImpl.java

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ public class ResultSetProcessingContextImpl implements ResultSetProcessingContex
8484
private Map<EntityPersister,Set<EntityKey>> subselectLoadableEntityKeyMap;
8585
private List<HydratedEntityRegistration> hydratedEntityRegistrationList;
8686

87-
private final LockModeResolver lockModeResolverDelegate;
88-
8987
/**
9088
* Builds a ResultSetProcessingContextImpl
9189
*
@@ -132,16 +130,6 @@ public ResultSetProcessingContextImpl(
132130
}
133131
}
134132
}
135-
this.lockModeResolverDelegate = new LockModeResolver() {
136-
@Override
137-
public LockMode resolveLockMode(EntityReference entityReference) {
138-
if ( queryParameters.getLockOptions() != null && queryParameters.getLockOptions()
139-
.getLockMode() != null ) {
140-
return queryParameters.getLockOptions().getLockMode();
141-
}
142-
return LockMode.READ;
143-
}
144-
};
145133
}
146134

147135
@Override
@@ -175,8 +163,11 @@ public ResultSet getResultSet() {
175163

176164
@Override
177165
public LockMode resolveLockMode(EntityReference entityReference) {
178-
final LockMode lockMode = lockModeResolverDelegate.resolveLockMode( entityReference );
179-
return LockMode.NONE == lockMode ? LockMode.NONE : lockMode;
166+
if ( queryParameters.getLockOptions() != null && queryParameters.getLockOptions()
167+
.getLockMode() != null ) {
168+
return queryParameters.getLockOptions().getLockMode();
169+
}
170+
return LockMode.READ;
180171
}
181172

182173
private Map<EntityReference,EntityReferenceProcessingState> identifierResolutionContextMap;

hibernate-core/src/main/java/org/hibernate/loader/plan2/exec/process/spi/AbstractRowReader.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.hibernate.event.spi.PostLoadEvent;
3535
import org.hibernate.event.spi.PreLoadEvent;
3636
import org.hibernate.internal.CoreLogging;
37+
import org.hibernate.internal.util.collections.CollectionHelper;
3738
import org.hibernate.loader.plan2.exec.process.internal.HydratedEntityRegistration;
3839
import org.hibernate.loader.plan2.exec.process.internal.ResultSetProcessingContextImpl;
3940
import org.hibernate.loader.spi.AfterLoadAction;
@@ -58,7 +59,7 @@ public Object readRow(ResultSet resultSet, ResultSetProcessingContextImpl contex
5859
final List<CollectionReferenceInitializer> arrayReferenceInitializers = getArrayReferenceInitializers();
5960
final List<CollectionReferenceInitializer> collectionReferenceInitializers = getCollectionReferenceInitializers();
6061

61-
final boolean hasEntityReferenceInitializers = entityReferenceInitializers != null && entityReferenceInitializers.size() > 0;
62+
final boolean hasEntityReferenceInitializers = CollectionHelper.isNotEmpty( entityReferenceInitializers );
6263

6364
if ( hasEntityReferenceInitializers ) {
6465
// 1) allow entity references to resolve identifiers (in 2 steps)

0 commit comments

Comments
 (0)