永続化のために JPA を使用する単純な EJB アプリケーションを作成しましたが、楽観的ロックが期待どおりに機能しないという問題があります。
Site
このアプリケーションには、データベース内の SITE という名前のテーブルのモデルを定義するという名前のクラスが含まれています。SITE テーブルには、注釈Site
を使用してクラスで参照される ROW_VERSION という名前の列が含まれています。@version
レコードが更新されるたびに、ROW_VERSION は 1 ずつインクリメントされます。
この問題は、アプリケーションがメソッドを使用して行を読み取ってからEntityManager find
、メソッドによって行が更新されるまでの間に行が変更された場合に発生しますEntityManager merge
。行の ROW_VERSION が 1 ずつインクリメントされているため、メソッドが呼び出されたときと同じではないため、スローされるEntityManager find
と予想OptimisticLockException
されますが、代わりに変更がテーブルに書き込まれ、メソッドによって行われた変更が上書きされます。他のプロセス。
アプリケーションは WebSphere 8.5 で実行され、コンテナーによって提供される OpenJPA を使用しています。
楽観的ロックがどのように機能するかを誤解していますか、それともそれを実現するために他に何かする必要がありOptimisticLockException
ますか?
Site クラスは次のとおりです。
@Entity
@Table(name="SITE")
public class Site {
@Id
@Column(name="SITE_ID")
private int id;
@Column(name="SITE_NAME")
private String siteName;
@Column(name="SITE_ADDRESS")
private String address;
@Column(name="ROW_VERSION")
@Version
private long rowVersion;
//getters and setters
}
アプリケーションは、ジェネリック DAO ラッパー クラスを使用して EntityManager メソッドを呼び出します。クラスの内容は次のとおりです。
public abstract class GenericDAO<T> {
private final static String UNIT_NAME = "Test4EJB";
@PersistenceContext(unitName = UNIT_NAME)
private EntityManager em;
private Class<T> entityClass;
public GenericDAO(Class<T> entityClass) {
this.entityClass = entityClass;
}
public T update(T entity) {
return em.merge(entity);
}
public T find(int entityID) {
return em.find(entityClass, entityID);
}
//other methods
}
更新- さらに調査を行ったところ、 http://pic.dhe.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic= %2Fcom.ibm.websphere.nd.multiplatform.doc%が見つかりました。 2Finfo%2Fae%2Fae%2Fcejb_genversionID.htmlしかし、@VersionColumn および @VersionStrategy アノテーションを追加した場合でも、OptimisticLockException をスローすることはできません。