エンティティのバージョン属性を使用したオプティミスティックロックは正常に機能し、実装が簡単です。
<version property="VERSION" type="int" column="EX_VERSION" />
エンティティには、次のタイプのプロパティがあります。
private int VERSION;
public int getVERSION() { return VERSION; }
public void setVERSION(int VERSION) { this.VERSION = VERSION; }
ここまでは順調ですね。これで、サービスメソッドは上記のエンティティのデータ転送オブジェクト(DTO)を返します。これは、ビューがHTMLで表示します。更新ページの場合、VERSION属性はHTMLの非表示フィールドに格納され、フォームとともに送信されます。
目的は、versionプロパティを使用して、表示される情報に古いバージョンが付随している場合にユーザーの更新が失敗するようにすることです。
コントローラは、更新された情報(バージョンプロパティを含む)を含むDTOを使用してサービスメソッドを呼び出すことでユーザーの更新要求に応答し、サービスメソッドはデータアクセスオブジェクト(DAO)を使用して変更を永続化します。
public void update(SimpleDTO dto) {
SimplyEntity entity = getSimpleDao().load(dto.getId());
copyProperties(dto, entity); // all properties, including VERSION copied to entity
getSimpleDao().update(entity);
}
問題は、copyProperties(...)によってエンティティにコピーされたバージョンプロパティがHibernateによって尊重されないことです。次のフォーラムで理由を突き止めました:https ://forum.hibernate.org/viewtopic.php?f = 1&t = 955893&p = 2418068
つまり、load()が呼び出されると、Hibernateはバージョンプロパティをセッションキャッシュにキャッシュし、その値が後で何に変更されてもかまいません。これが正しい動作であることに同意しますが、BossesからHTMLフォームプロパティを介してバージョンを渡すように指示されています(これに適したパターンがある場合は、ぜひ聞いてください)。
私が今探求している解決策の1つは、更新が行われる前に、hibernateTemplate.evict(simpleEntity)を使用してバージョンが設定された後、セッションからエンティティを削除することです。これがうまくいくことを願っていますが、効率的ではないようです。
セッションキャッシュからだけでなく、インスタンス自体のバージョンプロパティを確認するようにHibernateに依頼したいと思います。
回答ありがとうございます!
--LES