@@ -271,18 +271,36 @@ public override string SelectFragment(IJoinable rhs, string rhsAlias, string lhs
271
271
IAssociationType elementType = ( IAssociationType ) ElementType ;
272
272
if ( rhs . Equals ( elementType . GetAssociatedJoinable ( Factory ) ) )
273
273
{
274
- return ManyToManySelectFragment ( rhs , rhsAlias , lhsAlias , collectionSuffix ) ;
274
+ return ManyToManySelectFragment ( rhs , rhsAlias , lhsAlias , collectionSuffix , elementType ) ;
275
275
}
276
276
}
277
277
return includeCollectionColumns ? SelectFragment ( lhsAlias , collectionSuffix ) : string . Empty ;
278
278
}
279
279
280
- private string ManyToManySelectFragment ( IJoinable rhs , string rhsAlias , string lhsAlias , string collectionSuffix )
280
+ private string ManyToManySelectFragment (
281
+ IJoinable rhs ,
282
+ string rhsAlias ,
283
+ string lhsAlias ,
284
+ string collectionSuffix ,
285
+ IAssociationType elementType )
281
286
{
282
287
SelectFragment frag = GenerateSelectFragment ( lhsAlias , collectionSuffix ) ;
283
288
284
- string [ ] _elementColumnNames = rhs . KeyColumnNames ;
285
- frag . AddColumns ( rhsAlias , _elementColumnNames , elementColumnAliases ) ;
289
+ // We need to select in the associated entity table instead of taking the collection actual element,
290
+ // because filters can be applied to the entity table outer join. In such case, we need to return null
291
+ // for filtered-out elements. (It is tempting to switch to an inner join and just use
292
+ // SelectFragment(lhsAlias, collectionSuffix) for many-to-many too, but this would hinder the proper
293
+ // handling of the not-found feature.)
294
+ var elementColumnNames = string . IsNullOrEmpty ( elementType . RHSUniqueKeyPropertyName )
295
+ ? rhs . KeyColumnNames
296
+ // rhs is the entity persister, it does not handle being referenced through an unique key by a
297
+ // collection and always yield its identifier columns as KeyColumnNames. We need to resolve the
298
+ // key columns instead.
299
+ // 6.0 TODO: consider breaking again that IJoinable.SelectFragment interface for transmitting
300
+ // the OuterJoinableAssociation instead of its Joinable property. This would allow to get the
301
+ // adequate columns directly instead of re-computing them.
302
+ : ( ( IPropertyMapping ) rhs ) . ToColumns ( elementType . RHSUniqueKeyPropertyName ) ;
303
+ frag . AddColumns ( rhsAlias , elementColumnNames , elementColumnAliases ) ;
286
304
AppendIndexColumns ( frag , lhsAlias ) ;
287
305
AppendIdentifierColumns ( frag , lhsAlias ) ;
288
306
0 commit comments