Skip to content

Commit 385a861

Browse files
Fix many-to-many with property-ref
Fixes #1214
1 parent 6fedcb6 commit 385a861

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

src/NHibernate.Test/Async/PropertyRef/ManyToManyPropertyRefFixture.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ FROM ManyBs manybs0_
9898
Assert.That(loadedManyA.ManyBs.Count, Is.EqualTo(3));
9999
}
100100

101-
[Test, Ignore("Not fixed yet")]
101+
[Test]
102102
public async Task Getting_a_ManyA_object_with_fetchmode_join_will_workAsync()
103103
{
104104
ManyA loadedManyA;
@@ -142,7 +142,7 @@ bei NHibernate.Persister.Entity.AbstractEntityPersister.LoadByUniqueKey(String p
142142
bei NHibernate.Type.EntityType.LoadByUniqueKey(String entityName, String uniqueKeyPropertyName, Object key, ISessionImplementor session) in C:\Users\Armin\Projects\NHibernate\branches\2.1.x\nhibernate\src\NHibernate\Type\EntityType.cs:Zeile 552.
143143
*/
144144

145-
Assert.That(loadedManyA.ManyBs.Count, Is.EqualTo(3));
145+
Assert.That(loadedManyA.ManyBs, Has.Count.EqualTo(3).And.None.Null);
146146
}
147147
}
148148
}

src/NHibernate.Test/PropertyRef/ManyToManyPropertyRefFixture.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ FROM ManyBs manybs0_
8787
Assert.That(loadedManyA.ManyBs.Count, Is.EqualTo(3));
8888
}
8989

90-
[Test, Ignore("Not fixed yet")]
90+
[Test]
9191
public void Getting_a_ManyA_object_with_fetchmode_join_will_work()
9292
{
9393
ManyA loadedManyA;
@@ -131,7 +131,7 @@ bei NHibernate.Persister.Entity.AbstractEntityPersister.LoadByUniqueKey(String p
131131
bei NHibernate.Type.EntityType.LoadByUniqueKey(String entityName, String uniqueKeyPropertyName, Object key, ISessionImplementor session) in C:\Users\Armin\Projects\NHibernate\branches\2.1.x\nhibernate\src\NHibernate\Type\EntityType.cs:Zeile 552.
132132
*/
133133

134-
Assert.That(loadedManyA.ManyBs.Count, Is.EqualTo(3));
134+
Assert.That(loadedManyA.ManyBs, Has.Count.EqualTo(3).And.None.Null);
135135
}
136136
}
137137
}

src/NHibernate/Persister/Collection/BasicCollectionPersister.cs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)