开发者

NHibernate : Save, Delete then Save the same entity throws StaleStateException

开发者 https://www.devze.com 2023-02-04 15:06 出处:网络
Here is my the test case : [Test, Explicit] public void SaveDeleteSaveThrowsTest() { Produit produit = new Produit { Libelle = \"Test\" };

Here is my the test case :

[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);
        }
    }
}

The Ids are generated by HiLo.

If I assign 0 to the Id of the entity before saving it the 2nd time it开发者_Go百科 works in this simple case but doesn't work in more complex scenarios where I have a one to many relation (I get the exception "collection owner not associated with session" when trying to delete the parent entity).

Is there a way to make it work ? (save, delete the save again the same entity)


Don't you use lazy loading in many-to-* relationship? The problem is you are at first loading the entity, the close session and try to manipulate with (already detached) entity. In such a case sub-entities are proxies attached to closed session. You have to tell NHibernate to re-initialize the proxies: for each sub-entity call NHibernateUtil.Initialize.


Try Merge instead of SaveOrUpdate. It looks up the record in the database (additional select before insert or update). Note that Merge has a return value which returns the persistent instance while the given instance is still transient. You may need to clean the session or create a new session to make it work.


Try calling Session.Save or Session.Lock on the deleted produit object.

However, you should reconsider your design to avoid this problem in the first place. I would keep track of ids to be deleted in a separate collection then perform the deletes when the transaction is committed.

0

精彩评论

暂无评论...
验证码 换一张
取 消