我在双向一对多关系中有两个实体:
public class Storage
{
public IList<Box> Boxes { get; set; }
}
public class Box
{
public Storage CurrentStorage { get; set; }
}
和映射:
<class name="Storage">
<bag name="Boxes" cascade="all-delete-orphan" inverse="true">
<key column="Storage_Id" />
<one-to-many class="Box" />
</bag>
</class>
<class name="Box">
<many-to-one name="CurrentStorage" column="Storage_Id" />
</class>
一个Storage
可以有很多Boxes
,但一个Box
只能属于一个Storage
。我将它们映射,以便一对多具有级联的all-delete-orphan
.
当我尝试更改 Box 的Storage
. 假设我已经运行了这段代码:
var storage1 = new Storage();
var storage2 = new Storage();
storage1.Boxes.Add(new Box());
Session.Create(storage1);
Session.Create(storage2);
以下代码会给我一个例外:
// get the first and only box in the DB
var existingBox = Database.GetBox().First();
// remove the box from storage1
existingBox.CurrentStorage.Boxes.Remove(existingBox);
// add the box to storage2 after it's been removed from storage1
var storage2 = Database.GetStorage().Second();
storage2.Boxes.Add(existingBox);
Session.Flush(); // commit changes to DB
我得到以下异常:
NHibernate.ObjectDeletedException : 已删除的对象将被级联重新保存(从关联中删除已删除的对象)
发生此异常是因为我将级联设置为all-delete-orphan
. 第一个Storage
检测到我Box
从其集合中删除了 并将其标记为删除。但是,当我将它添加到第二个Storage
(在同一个会话中)时,它会尝试再次保存该框并ObjectDeletedException
抛出该框。
我的问题是,如何在不遇到此异常的情况下Box
更改其父级?Storage
我知道一种可能的解决方案是将级联更改为 just all
,但随后我失去了让 NHibernate 自动删除 a 的能力Box
,只需将其从 a 中删除Storage
而不将其与另一个重新关联。或者这是唯一的方法,我必须手动调用Session.Delete
盒子才能删除它?