@@ -271,18 +271,36 @@ public override string SelectFragment(IJoinable rhs, string rhsAlias, string lhs
271271 IAssociationType elementType = ( IAssociationType ) ElementType ;
272272 if ( rhs . Equals ( elementType . GetAssociatedJoinable ( Factory ) ) )
273273 {
274- return ManyToManySelectFragment ( rhs , rhsAlias , lhsAlias , collectionSuffix ) ;
274+ return ManyToManySelectFragment ( rhs , rhsAlias , lhsAlias , collectionSuffix , elementType ) ;
275275 }
276276 }
277277 return includeCollectionColumns ? SelectFragment ( lhsAlias , collectionSuffix ) : string . Empty ;
278278 }
279279
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 )
281286 {
282287 SelectFragment frag = GenerateSelectFragment ( lhsAlias , collectionSuffix ) ;
283288
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 ) ;
286304 AppendIndexColumns ( frag , lhsAlias ) ;
287305 AppendIdentifierColumns ( frag , lhsAlias ) ;
288306
0 commit comments