NHibernat报错:A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance

nhibernate 相关文章  NHibernate的使用级联更新相当的简单,但今天在使用的时候却碰到一个错误,在更新对象的一个关联对象时报错:A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance

  这个问题出现的字面意思是,我们使用了级联更新:all-delete-orphan,但是遗憾的是,使用的Collection所在的宿主对象不再能得到引用,因此导致更新失败。既然是这样就看看引用了,在出错的代码处,代码如下:

public void SaveModel(Product model)
{
    /*some logic code.*/
    var p = _pRepository.Get(model.id);
    /* 这里设置了需要删除的分类id:tc_delete_id和需要更新的分类Id:tc_update_id*/

    IList<PT> need_to_update = (from t in p.PTList
            where t.Category.Id == tc_update_id
            select t).ToList();
    IList<PT> need_to_add = GetNeedAddList();
    p.PTList.Clear();
    p.PTList = need_to_update.Union(need_to_add).ToList();
    _pRepository.Update(p);
}

代码中就是对p中的PTList进行更新而已,而PTList就是报错中出现的不能更新的那个对象,设置的是all-delete-orphan关系。这么看没有任何问题,因为需要删除的列表不好提取,就直接将需要更新的取出来,在添加上需要新增的列表,最后将结果导入到PTList中。

网上查找很多都是莫名其妙的解决方法, 当然,大多数还是Hibernate的,而不是NHibernate的,作为NHibernate的新手,对此总是有那么点丈二和尚——摸不着头,所以一切还得自己来。

看报错,应该就是PTList的引用出问题了,也许你在用NHibernate的刚开始碰到过如下操作:

    var p = _pRepository.Get(model.id);
    _pRepository.Update(model);

我比较愚钝,这个错误被我犯过,系统会报在Session中已经有一个对象了,所以导致Update失败。

为什么要说这个呢,我感觉应该是差不多的逻辑,应该是NHibernate对于在Session内的对象会进行维护,而但我们操作的时候,一旦用新的对象(NHibernate已经维护一份)来替换NHibernate维护的那份时,如果没有适当的操作,应该就会报错了。

既然是这个想法,那么让我们来试试吧:

在p.PTList.Clear();后面添加上:

Session.Clear(); // 这个是清除所有Session中的缓存。

运行吧,奇迹诞生了,没有报错了,看来猜想是对的。不过等等,不要高兴的太早了,你会发现系统竟然没有删除我们要删除的内容?!这个缓存清除,让系统无法知晓那些对象该删除了。这个不是我们想要的。看来我们猜想是对的,不过,操作起来却不能这样。

既然这样,我们就好好的让NHibernate来维护这个关系吧。换种思路,虽然艰难了一点,寻找出需要删除的对象:

    IList<PT> need_to_delete = (from t in p.PTList
            where t.Category.Id == tc_delete_id
            select t).ToList();

然后将PTList中的这些对象删除掉。之后,添加需要的对象。再来更新,问题得到解决。

这是一次浅尝辄止的摸索,对于NHibernate的菜鸟来说,暂时还没有更好的方法来解决,如果你有,请告诉我。

Saturday, July 28, 2012 | NHibernate

文章评论

No comments posted yet.

发表评论

Please add 3 and 3 and type the answer here:

关于博主

  一枚成分复杂的网络IT分子,常年游弋于电子商务,属于互联网行业分类中的杂牌军。当前正在待业中...