NHibernate--使用集合缓存时重复结果

NHibernate--使用集合缓存时重复结果,nhibernate,nhibernate-caches,Nhibernate,Nhibernate Caches,当使用具有多层双向父子孙一对多关系的二级缓存时,我从NHibernate获得了非常奇怪的行为: int id; using(var session = sessionFactory.OpenSession()) { var parent = new Parent(); var child1 = parent.AddChild(); child1.AddGrandChild(); var child2 = parent.AddChild(); child2

当使用具有多层双向父子孙一对多关系的二级缓存时,我从NHibernate获得了非常奇怪的行为:

int id;

using(var session = sessionFactory.OpenSession())
{
    var parent = new Parent();
    var child1 = parent.AddChild();
    child1.AddGrandChild();
    var child2 = parent.AddChild();
    child2.AddGrandChild();
    session.Save(parent);
    session.Flush(); // force id generation
    id = parent.Id;
}

using(var session = sessionFactory.OpenSession())
{
    var parent = session.Get<Parent>(id);
    parent.Children.Should().HaveCount(2); // but is actually 3; second child duplicated
}
映射:

public class ParentMap : ClassMap<Parent>
{
    public ParentMap()
    {
        Id(p => p.Id).GeneratedBy.Identity();
        HasMany(p => p.Children)
            .Access.CamelCaseField()
            .Inverse()
            .Cascade.AllDeleteOrphan()
            .Cache.ReadWrite();
        Cache.ReadWrite();
    }
}

public class ChildMap : ClassMap<Child>
{
    public ChildMap()
    {
        Id(c => c.Id).GeneratedBy.Identity();
        HasMany(c => c.GrandChildren)
            .Access.CamelCaseField()
            .Inverse()
            .Cascade.AllDeleteOrphan()
            .Cache.ReadWrite();
        References(c => c.Parent);
        Cache.ReadWrite();
    }
}

public class GrandChildMap : ClassMap<GrandChild>
{
    public GrandChildMap()
    {
        Id(c => c.Id).GeneratedBy.Identity();
        References(c => c.Parent);
        Cache.ReadWrite();
    }
}

尽管如此,我仍然不明白这里发生了什么,所以对这件事的任何见解都是受欢迎的:-.

您是否尝试过使用事务而不是会话刷新?像

using(var session = sessionFactory.OpenSession())
using(var transaction = session.BeginTransaction())
{
    var parent = new Parent();
    [...]
    parent.Save();
    transaction.Commit();
    id = parent.Id;
}

也许这会有帮助。我曾经遇到过一个类似的问题,我可以通过使用事务来解决。

不,不是这样。。。1我不进行刷新,而进行提交,无论如何都没有任何意义,但如果id为2,则强制生成。因为我为写入和后续读取打开了单独的会话,所以这两个操作都有自己的隐式事务。3通常我使用显式事务,我只是把它们放在这里让brevityTo澄清一下:在真正的代码中,两个会话/事务对应于单独的web服务请求。
    public ChildMap()
    {
       // ...
        HasMany(c => c.GrandChildren) // removed Cache.ReadWrite() here
            /* ... */;

        // added IncludeAll() to make sure lazily fetched collections get cached
        Cache.ReadWrite().IncludeAll(); 
    }
using(var session = sessionFactory.OpenSession())
using(var transaction = session.BeginTransaction())
{
    var parent = new Parent();
    [...]
    parent.Save();
    transaction.Commit();
    id = parent.Id;
}