web-dev-qa-db-ja.com

Hibernateの多対1マッピングで逆カスケード削除を定義する方法

私には2つのクラスAとBがあります。多くのBは単一のAと関連付けることができるため、BからAへの多対1の関係になります。次のように関係をマッピングしました。

<class name="A" table="tbl_A">
  <property name="propA" column="colA"/>
</class>
<class name="B" table="tbl_B">
  <property name="propB" column="colB"/>
  <many-to-one name="a" class="A" column="col1" cascade="delete"/>
</class>

AにはBにマップされたものはありません。これを念頭に置いて、関連付けられているAが削除されたときにBを削除する予定です。これは、Bの多対1の関連付けでinverse = "true"を定義できれば可能でしたが、Hibernateではそれが許可されていません。

誰かがこれを手伝うことができますか?このためにAに何も書きたくありません。

18
Monis Iqbal

休止状態は、定義された関連付けに沿ってのみカスケードします。 AがBについて何も知らない場合、Aで何もしないとBに影響しません。

したがって、Pascalの提案は、必要なことを実行する最も簡単な方法です。

<class name="A" table="tbl_A">
  ...
  <set name="myBs" inverse="true" cascade="all,delete-Orphan">
    <key column="col1"/>
    <one-to-many class="B"/>
  </set>
</class>

<class name="B" table="tbl_B">
  ...
  <many-to-one name="a" class="A" column="col1" not-null="true"/>
</class>

元のコードにあるようにBcascade="delete"を設定しても、期待どおりの動作が行われないことに注意してください。Hibernateに「Bが削除された場合はAを削除する」ように指示されるため、制約違反が発生する可能性があります。 (そのAにリンクされている他のBがある場合)。

BのコレクションをAに絶対に追加できない場合(そのような状況を実際に考えることはできませんが)、他の唯一の選択肢は、外部キーレベルでAからBへのカスケード削除を定義することです。 Aが削除されると、Bも削除されます。

ただし、HibernateでAを削除する方法に細心の注意を払う必要があるため、これはかなり醜い解決策です。

  1. Aを削除する前にセッションをフラッシュする必要があります(Bの更新が保留されていると、エラーが発生するか、Aと一部のBがバックグラウンドで再挿入される可能性があります)
  2. AにリンクされているすべてのB(および、A側からの関係を維持していないため、all Bs)は、すべてのアクティブなセッションと2次キャッシュから削除する必要があります。
24
ChssPly76

cascade="all,delete-Orphan"アソシエーションでAからBにone-to-manyする必要があると思います。

7
Pascal Thivent