ここでわずかな問題:
私は2つのエンティティクラスを持っているとしましょう
class Parent {
Set<Child> children;
}
class Child {
SomethingElse reference;
}
現在、マッピングは基本的に次のとおりです。
<class name="Parent" lazy="false">
<set name="children" lazy="false" cascade="all-delete-orphan">
<key column="parent_id"/>
<one-to-many class="Child"/>
</set>
</class>
(ここでは ID マッピングとフィールドを省略しました。通常の生成 ID を使用します)
親のリストから要素を削除してから親をコミットするときのように、基本的にクリーンなデータベースを維持する必要があり、それに応じて削除された子データベースのエントリを削除する必要があります。子インスタンスは、後で削除できるようにする必要がある他のエンティティを参照するため、子インスタンスがデータベースに残っていると、参照されたオブジェクトを削除できません。
これまでにわかったこと: 休止状態の PersistentCollection ラッパーを所定の位置に保持する場合、以下で試したことはどれも機能するはずです。問題は、データベース オブジェクトがフレームワークのいくつかのレイヤーを通過することです。これには、Bean プロパティの抽象化を使用してセッターを呼び出す UI フレームワークと、オブジェクトのクローンを作成して前後にシリアル化するネットワーク通信レイヤーが含まれます。これらのレイヤーはどちらもコレクション インスタンスを内部的に置き換えるため、これらの PersistentCollection ラッパーを削除します。そうしないようにこれらを書き換えることはオプションではありません。
そうは言っても、私が試した8つのことはうまくいきませんでした:
1) リレーションを cascade="all" として構成し、session.update(parent) を使用します。
2) 関係を cascade="all-delete-orphan" として構成し、session.update(parent) を使用します。
3) リレーションを cascade="all" として構成し、session.merge(parent) を使用します
これらはすべて、「UPDATE CHILD SET parent.id = null WHERE parent.id = ...」を実行する休止状態になります。これは、親インスタンスをリロードするときに親リストから子を削除することに成功しますが、子インスタンスはデータベースに残り、参照されている他のエンティティを削除できません。
4-6) 構成 1-3 を使用し、さらに親キー列を非 null として定義する
これにより、休止状態は何もしなくなります。別の投稿で、キー列を非 null にすると削除されることを読みました。null への更新はオプションではなくなったため可能ですが、機能しません。コレクションから子を削除し、変更をコミットしてデータベースからインスタンスをリロードすると、子が再び表示されます。
7+8) 親キーが null 可能かどうかは問題ではありませんが、リレーションを cascade=all-delete-orphans として構成し、session.merge(parent) を使用します
これにより、PersistentCollection ラッパーが削除されたため、hibernate は例外「cascade="all-delete-orphan" を持つコレクションは、所有エンティティ インスタンスによって参照されなくなりました」をスローします。
私の問題を解決するために必要なのは、休止状態でオプション 1 ~ 3 のクエリを UPDATE ではなく DELETE として実行することだけです。PersistentCollection ラッパーなしでこれらを削除する方法でマッピングを構成するオプションが見つからないことを願っていますが、現在、そのようなオプションはないように見えます。これを設定する方法があるかどうか誰かが知っていますか?
/編集:明確にするために、私がしたいことの例:
Parent parent = new Parent();
parent.setChildren(new HashSet<Child>(Arrays.asList(new Child()))));
session.insert(parent)
// this correctly results in (approximately):
// SQL> INSERT INTO PARENT ...
// SQL> INSERT INTO CHILD ...
parent.setChildren(new HashSet<Child>()); // using .clear() is not an option.
session.update(parent);
// this results in:
// SQL> UPDATE CHILD set parent_id = null WHERE parent_id = ${id.of.parent}
// but i need this to result in:
// SQL> DELETE FROM CHILD WHERE parent_id = ${id.of.parent}