NHibernate:保存,删除然后保存相同的实体抛出StaleStateException

时间:2011-01-11 10:29:53

标签: c# .net nhibernate

这是我的测试用例:

[Test, Explicit]
public void SaveDeleteSaveThrowsTest()
{
    Produit produit = new Produit { Libelle = "Test" };

    using (ISession session = this.SessionProvider.OpenSession())
    {
        session.FlushMode = FlushMode.Auto;

        using (ITransaction transaction = session.BeginTransaction())
        {                    
            session.SaveOrUpdate(produit);
            transaction.Commit();
        }

        using (ITransaction transaction = session.BeginTransaction())
        {
            session.Delete(produit);
            transaction.Commit();
        }

        using (ITransaction transaction = session.BeginTransaction())
        {
            session.SaveOrUpdate(produit);
            Assert.Throws(typeof(StaleStateException), transaction.Commit);
        }
    }
}

Ids由HiLo生成。

如果我在保存它之前将0分配给实体的Id,那么第二次它在这个简单的情况下工作但是在我有一对多关系的更复杂的场景中不起作用(我得到例外“集合所有者与尝试删除父实体时的会话无关。

有没有办法让它发挥作用? (保存,删除再次保存相同的实体)

3 个答案:

答案 0 :(得分:2)

你不是在多对多关系中使用延迟加载吗? 问题是您首先加载实体,关闭会话并尝试使用(已经分离的)实体进行操作。在这种情况下,子实体是附加到封闭会话的代理。你必须告诉NHibernate重新初始化代理:为每个子实体调用NHibernateUtil.Initialize。

答案 1 :(得分:1)

尝试使用Merge代替SaveOrUpdate。它查找数据库中的记录(在插入或更新之前进行额外选择)。请注意,Merge具有返回值,该值返回持久实例,而给定实例仍然是瞬态的。您可能需要清理会话或创建新会话以使其正常工作。

答案 2 :(得分:0)

尝试在已删除的produit对象上调用Session.Save或Session.Lock。

但是,您应该重新考虑您的设计,以避免这个问题。我会跟踪要在单独的集合中删除的ID,然后在提交事务时执行删除。