Closed
Description
Recently I've upgraded NH to version 5.4.2 and I've found an issue related to many-to-many relation. Here is a test case:
public class Entity
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
public virtual ICollection<Entity> Children { get; set; } = new HashSet<Entity>();
public virtual ICollection<Entity> Parents { get; set; } = new HashSet<Entity>();
}
public class EntityMapping : ClassMapping<Entity>
{
public EntityMapping()
{
Id(x => x.Id, map => map.Generator(Generators.GuidComb));
Property(
x => x.Name
);
Set(
x => x.Children,
v =>
{
v.Table("OrganisationUnitParent_OrganisationUnitChildren");
v.Cascade(Cascade.None);
v.Inverse(true);
v.Key(x =>
{
x.Column("ParentOuId");
x.NotNullable(true);
});
v.Lazy(CollectionLazy.Lazy);
v.Fetch(CollectionFetchMode.Join);
},
h => h.ManyToMany(m => m.Column("ChildOuId"))
);
Set(
x => x.Parents,
v =>
{
v.Table("OrganisationUnitParent_OrganisationUnitChildren");
v.Cascade(Cascade.All);
v.Key(x =>
{
x.Column("ChildOuId");
x.NotNullable(true);
});
v.Lazy(CollectionLazy.Lazy);
v.Fetch(CollectionFetchMode.Join);
},
h => h.ManyToMany(m => m.Column("ParentOuId"))
);
}
}
[Test]
public void Test1()
{
var person = new Entity();
person.Name = "pers";
Session.SaveOrUpdate(person);
var job = new Entity();
job.Name = "job";
Session.SaveOrUpdate(job);
job.Children.Add(person);
person.Parents.Add(job);
Session.SaveOrUpdate(job);
Session.SaveOrUpdate(person);
Session.Flush();
using (var newSession = _sessionFactory.OpenSession())
{
///////1////////
//this query causes the problem. If you comment it, this test will pass
var allOUs = newSession
.QueryOver<Entity>()
.Fetch(SelectMode.Fetch, x => x.Children)
.Fetch(SelectMode.Fetch, x => x.Parents)
.TransformUsing(Transformers.DistinctRootEntity)
.List();
var jobDb = newSession.Get<Entity>(job.Id);
var personDb = newSession.Get<Entity>(person.Id);
Assert.AreEqual(1, jobDb.Children.Count);
///////2////////
Assert.AreEqual(1, personDb.Parents.Count);//because of this issue, here we have 0 instead of 1
//now let's remove all members
personDb.Parents.Clear();
jobDb.Children.Clear();
newSession.Update(personDb);
newSession.Flush();
}
using (var newSession = _sessionFactory.OpenSession())
{
var jobDb = newSession.Get<Entity>(job.Id);
var personDb = newSession.Get<Entity>(person.Id);
Assert.AreEqual(0, jobDb.Children.Count);
Assert.AreEqual(0, personDb.Parents.Count);
}
}
In this test personDb.Parents.Count (///////2////////) has no elements and should be 1 item. This is because of query above (///////1////////). If you comment this query, the test will pass.
This test works good in version 5.3, and in version v5.4.0+ it fails.
If you need more info, please let me know.