68
68
* @author Steve Ebersole
69
69
*/
70
70
public class LoadQueryJoinAndFetchProcessor {
71
- private static final Logger log = CoreLogging .logger ( LoadQueryJoinAndFetchProcessor .class );
71
+ private static final Logger LOG = CoreLogging .logger ( LoadQueryJoinAndFetchProcessor .class );
72
72
73
73
private final AliasResolutionContextImpl aliasResolutionContext ;
74
74
private final QueryBuildingParameters buildingParameters ;
@@ -91,6 +91,7 @@ public LoadQueryJoinAndFetchProcessor(
91
91
}
92
92
93
93
public void processQuerySpaceJoins (QuerySpace querySpace , SelectStatementBuilder selectStatementBuilder ) {
94
+ LOG .debug ( "processing queryspace " + querySpace .getUid () );
94
95
final JoinFragment joinFragment = factory .getDialect ().createOuterJoinFragment ();
95
96
processQuerySpaceJoins ( querySpace , joinFragment );
96
97
@@ -127,7 +128,16 @@ private void renderJoin(Join join, JoinFragment joinFragment) {
127
128
else if ( EntityQuerySpace .class .isInstance ( join .getRightHandSide () ) ) {
128
129
// do not render the entity join for a one-to-many association, since the collection join
129
130
// 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 ||
131
141
! CollectionQuerySpace .class .cast ( join .getLeftHandSide () ).getCollectionPersister ().isOneToMany () ) {
132
142
renderEntityJoin ( join , joinFragment );
133
143
}
@@ -371,34 +381,34 @@ private void renderSqlJoinToCollectionTable(
371
381
);
372
382
}
373
383
374
- // private void renderManyToManyJoin(
375
- // CollectionReferenceAliases aliases,
376
- // CollectionQuerySpace rightHandSide,
384
+ private void renderManyToManyJoin (
385
+ CollectionReferenceAliases aliases ,
386
+ CollectionQuerySpace rightHandSide ,
377
387
// 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
+
402
412
//
403
413
// {
404
414
// // add join fragments from the owner table -> collection table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -420,45 +430,45 @@ private void renderSqlJoinToCollectionTable(
420
430
// queryableCollection.whereJoinFragment( collectionTableAlias, false, true )
421
431
// );
422
432
// }
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
+
462
472
// private void renderOneToManyJoin(
463
473
// CollectionReferenceAliases aliases,
464
474
// CollectionQuerySpace rightHandSide,
@@ -699,8 +709,9 @@ private void processCollectionFetch(
699
709
selectStatementBuilder .appendSelectClauseFragment (
700
710
joinableCollection .selectFragment (
701
711
(Joinable ) queryableCollection .getElementPersister (),
702
- ownerTableAlias ,
712
+ elementTableAlias ,
703
713
collectionTableAlias ,
714
+
704
715
aliases .getEntityElementColumnAliases ().getSuffix (),
705
716
aliases .getCollectionColumnAliases ().getSuffix (),
706
717
true
@@ -731,7 +742,7 @@ private void processCollectionFetch(
731
742
final EntityReferenceAliases entityReferenceAliases = new EntityReferenceAliases () {
732
743
@ Override
733
744
public String getTableAlias () {
734
- return aliases .getElementTableAlias ();
745
+ return aliases .getCollectionTableAlias ();
735
746
}
736
747
737
748
@ Override
0 commit comments