3

私には 2 つのエンティティがParentありChildます。1 対多の関係にあります。はParentバージョン管理されています。つまり、@Version フィールドがあります。私の目標は、バージョンのParentChildエンティティの両方への変更を同期することです。Parent

たとえば、あるスレッドが を更新しParent、別のスレッドがその の 1 つを更新するChildと、OptimisticLockException が発生します。

出来ますか?

Childのバージョンをインクリメントする @PreUpdate に @PreUpdate を追加しようとしましたParentが、Hibernate はバージョンをチェックした後にのみリスナーを実行するように見えるため、トランザクションはとにかく正常にコミットされるため、役に立ちませんでした。

可能であれば、どのように実装できますか?

4

2 に答える 2

1

まず、明確にする必要がある 2 つの問題があります。

  1. コレクションの変更ではなく、特定の子インスタンスに対して行われた更新をキャッチしようとしていると思います (たとえば、新しい子が追加されたり、古い子が削除されたりします)。後者はデフォルトで親のバージョンをインクリメントします。

  2. 「あるスレッドが親を更新」し、「別のスレッドが子を更新」と言うとき、変更はすぐにフラッシュされると想定しています。つまり、一連のイベントは次のとおりです。別のスレッドが、以前のバージョンの親を指す子を更新しようとして失敗します。そうでない場合、楽観的ロックは役に立ちません。

1適切な分離レベルを設定することで「トランザクションコミット」ビットを回避できる場合がありますが、それは並行環境で解決するよりも多くの問題を引き起こす可能性があります。「即時フラッシュ」要件を回避することはできません。

上記の仮定が正しいと仮定すると、Child インスタンスを更新する前に、EntityManager.lock()メソッドを使用してParentをロックする必要があります。詳細については、 LockModeTypeおよびHibernate EntityManager のドキュメントを参照してください。

于 2009-09-11T00:30:45.447 に答える
1

Child をエンティティではなくコンポーネントにしてみましたか?

デフォルトの Hibernate 操作は、要件により適している場合があります。親は実体であり、子はより大きな全体の要素と見なされるという考え方です。

Hibernate では、これをデフォルトの親子関係と見なす必要があります。エンティティ間の親子関係は、可能ではありますが、あまり自然ではありません。

于 2009-09-09T13:34:15.230 に答える