セッションからオブジェクトを切り離した多層アプリケーションに問題があります。GUI を介して親オブジェクトのプロパティを編集し、子オブジェクト (親内のコレクション) を追加、編集、および削除します。親オブジェクトとその子の間の孤立した削除を含むすべてをカスケードしています。
オブジェクトをセッション (saveOrUpdate など) に関連付けると、挿入と削除が発生しますが、GUI のユーザーが削除してから追加すると、発生する順序が子オブジェクトのビジネス (自然) キーの一意の制約に違反します。同じビジネス キーに戻します)。
本「Hibernate in Action」とオンラインの参照ページを調べた後、項目が削除されてから子のコレクションに再度追加されたときに一意の制約に違反するという問題に対する決定的な答えを見つけることができなかったようです親オブジェクト。
Hibernate は、以下の Hibernate ドキュメントの行に従って、挿入の前に削除を発行しません。
ドキュメントには、flush() の呼び出しに関する次の順序が記載されています。
- 保存が呼び出されたのと同じ順序でのすべてのエンティティの挿入
- すべてのエンティティの更新
- すべてのコレクションの削除
- すべてのコレクション要素の削除、更新、および挿入
- すべてのコレクションの挿入
- 削除が呼び出されたのと同じ順序でのすべてのエンティティの削除。
順序が「削除、更新、および挿入」であることを暗示していますか、それともドキュメントがここで順序を厳密に指定していませんか?
コレクション要素の削除の前に挿入が行われているため、Hibernate はこの順序と一致していないようです。Hibernate が常に最初に挿入を発行する場合、この問題に対する推奨される解決策は何ですか? Hibernate の世界から出て、この関係を自分で処理する必要がありますか?
もしそうなら、問題ありませんが、Hibernate で利用可能な解決策がある場合、これを回避するためにコーディングする必要はありません。
AND のサロゲート主キーを持つテーブルがある場合、別の列に一意の制約がある場合、マッピング ファイルの属性を微調整することで、Hibernate が flush() を呼び出すときに一意の制約を尊重するようにできますか?
オンライン リファレンス ドキュメントから:「ただし、Hibernate には、(制約違反を回避するために) SQL INSERT および UPDATE ステートメントを正しく配置するための十分な情報がなく、いくつかの情報が必要です。
双方向の関連付けを適切に処理するのに役立ちます。アソシエーションの片側を反転させると、Hibernate は基本的にそれを無視し、反対側のミラーと見なすようになります。方向ナビゲーション モデルを SQL データベース スキーマに変換する際に、Hibernate がすべての問題を解決するために必要なことはこれだけです。」