diff --git a/src/NHibernate.Test/Async/PropertyRef/ManyToManyPropertyRefFixture.cs b/src/NHibernate.Test/Async/PropertyRef/ManyToManyPropertyRefFixture.cs index ac3ef58b223..1bb2716733f 100644 --- a/src/NHibernate.Test/Async/PropertyRef/ManyToManyPropertyRefFixture.cs +++ b/src/NHibernate.Test/Async/PropertyRef/ManyToManyPropertyRefFixture.cs @@ -98,7 +98,7 @@ FROM ManyBs manybs0_ Assert.That(loadedManyA.ManyBs.Count, Is.EqualTo(3)); } - [Test, Ignore("Not fixed yet")] + [Test] public async Task Getting_a_ManyA_object_with_fetchmode_join_will_workAsync() { ManyA loadedManyA; @@ -142,7 +142,7 @@ bei NHibernate.Persister.Entity.AbstractEntityPersister.LoadByUniqueKey(String p 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. */ - Assert.That(loadedManyA.ManyBs.Count, Is.EqualTo(3)); + Assert.That(loadedManyA.ManyBs, Has.Count.EqualTo(3).And.None.Null); } } } diff --git a/src/NHibernate.Test/PropertyRef/ManyToManyPropertyRefFixture.cs b/src/NHibernate.Test/PropertyRef/ManyToManyPropertyRefFixture.cs index 2a6734519f5..054cba44957 100644 --- a/src/NHibernate.Test/PropertyRef/ManyToManyPropertyRefFixture.cs +++ b/src/NHibernate.Test/PropertyRef/ManyToManyPropertyRefFixture.cs @@ -87,7 +87,7 @@ FROM ManyBs manybs0_ Assert.That(loadedManyA.ManyBs.Count, Is.EqualTo(3)); } - [Test, Ignore("Not fixed yet")] + [Test] public void Getting_a_ManyA_object_with_fetchmode_join_will_work() { ManyA loadedManyA; @@ -131,7 +131,7 @@ bei NHibernate.Persister.Entity.AbstractEntityPersister.LoadByUniqueKey(String p 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. */ - Assert.That(loadedManyA.ManyBs.Count, Is.EqualTo(3)); + Assert.That(loadedManyA.ManyBs, Has.Count.EqualTo(3).And.None.Null); } } } diff --git a/src/NHibernate/Persister/Collection/BasicCollectionPersister.cs b/src/NHibernate/Persister/Collection/BasicCollectionPersister.cs index 6343ae4b6ce..276ab028874 100644 --- a/src/NHibernate/Persister/Collection/BasicCollectionPersister.cs +++ b/src/NHibernate/Persister/Collection/BasicCollectionPersister.cs @@ -271,18 +271,36 @@ public override string SelectFragment(IJoinable rhs, string rhsAlias, string lhs IAssociationType elementType = (IAssociationType) ElementType; if (rhs.Equals(elementType.GetAssociatedJoinable(Factory))) { - return ManyToManySelectFragment(rhs, rhsAlias, lhsAlias, collectionSuffix); + return ManyToManySelectFragment(rhs, rhsAlias, lhsAlias, collectionSuffix, elementType); } } return includeCollectionColumns ? SelectFragment(lhsAlias, collectionSuffix) : string.Empty; } - private string ManyToManySelectFragment(IJoinable rhs, string rhsAlias, string lhsAlias, string collectionSuffix) + private string ManyToManySelectFragment( + IJoinable rhs, + string rhsAlias, + string lhsAlias, + string collectionSuffix, + IAssociationType elementType) { SelectFragment frag = GenerateSelectFragment(lhsAlias, collectionSuffix); - string[] _elementColumnNames = rhs.KeyColumnNames; - frag.AddColumns(rhsAlias, _elementColumnNames, elementColumnAliases); + // We need to select in the associated entity table instead of taking the collection actual element, + // because filters can be applied to the entity table outer join. In such case, we need to return null + // for filtered-out elements. (It is tempting to switch to an inner join and just use + // SelectFragment(lhsAlias, collectionSuffix) for many-to-many too, but this would hinder the proper + // handling of the not-found feature.) + var elementColumnNames = string.IsNullOrEmpty(elementType.RHSUniqueKeyPropertyName) + ? rhs.KeyColumnNames + // rhs is the entity persister, it does not handle being referenced through an unique key by a + // collection and always yield its identifier columns as KeyColumnNames. We need to resolve the + // key columns instead. + // 6.0 TODO: consider breaking again that IJoinable.SelectFragment interface for transmitting + // the OuterJoinableAssociation instead of its Joinable property. This would allow to get the + // adequate columns directly instead of re-computing them. + : ((IPropertyMapping) rhs).ToColumns(elementType.RHSUniqueKeyPropertyName); + frag.AddColumns(rhsAlias, elementColumnNames, elementColumnAliases); AppendIndexColumns(frag, lhsAlias); AppendIdentifierColumns(frag, lhsAlias);