拡張セッション/自動バージョン管理を使用した標準的な楽観的同時実行制御シナリオで遊んでいます。最初のトランザクションでロードし、変更のためにユーザーに提示し、2番目のトランザクションで保存するエンティティがあり、両方のトランザクションが同じセッションを共有しています。エンティティが何らかの形で 2 番目のトランザクションの最後に変更された後、バージョンの不一致が検出された場合、並行トランザクションがその間にエンティティの次のバージョンを保存したことを意味する session.flush()
がスローされる可能性があります。StaleObjectStateException
このようなエラーを最も簡単な方法で処理したいと思います。現在の変更を失うエンティティをリロードし、編集と保存を再度続行するだけです。最初にこれを試しました:
session.refresh(entity);
しかし、この更新されたエンティティを変更して保存しようとすると、StaleObjectStateException
更新されてバージョン番号が一貫しているように見えても、同じ . refresh()
はい、延長セッションでの使用はお勧めできないことは知っていますが、その理由はわかりません。この行動は、それが推奨されない理由に関連していますか?
次に、使用を避けるために次の方法を試しましたsession.refresh()
。
session.evict(entity);
entity = session.load(MyEntity.class, id);
しかし、それStaleObjectStateException
は実際には古くないエンティティを保存するときに発生します。
例外に対処できた唯一の方法は次のとおりです。
session.clear();
entity = session.load(MyEntity.class, id);
しかし、私の具体的なエンティティに関するものsession.clear()
と同じではありませんか?session.evict()
再開するには、私の質問は次のとおりです。
- が行われ
StaleObjectStateException
ない限り、リロードされたエンティティでまだスローされるのはなぜですか?session.clear()
- 同じセッションで既にロードされているエンティティをリロードする正しい方法は何ですか?なぜ
refresh()
悪いのですか? 会話を実装するこのアプローチには何か問題がありますか?
二次キャッシュなしで Hibernate 4.1.7.Final を使用しています。
私の質問が繰り返されている場合は申し訳ありませんが、深い説明を見つけることができません...