私は双方向の1対多の関係にある2つのエンティティを持っています:
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>
AStorage
は多数持つことができますBoxes
が、aBox
は1つにしか属することができませんStorage
。1対多がのカスケードを持つようにそれらをマッピングしましたall-delete-orphan
。
ボックスを変更しようとすると問題が発生し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
、削除のマークを付けました。ただし、(同じセッションで)2番目に追加するとStorage
、ボックスを再度保存しようとし、ObjectDeletedException
がスローされます。
私の質問は、この例外が発生することなくBox
、親を変更するにはどうすればよいですか?Storage
考えられる解決策の1つは、カスケードを単にに変更することですall
が、NHibernateでを削除し、別のカスケードに再度関連付けないBox
ようにするだけで、自動的に削除することができなくなります。Storage
それとも、これがそれを行う唯一の方法であり、それSession.Delete
を削除するためにボックスを手動で呼び出す必要がありますか?