2017-07-17 2 views
1

SQLServerでJPAオプティミスティックロックを設定しようとしています。その目的のために私はTIMESTAMP列を使用します(SQLServer TIMESTAMPは増分する数値であり、日付または時刻を保持しません)。JPA optimistic lock with SQLServer TIMESTAMP

ます。com.microsoft.sqlserver.jdbc.SQLServerException:

は、そうでない場合、私は例外になるだろう、私はfalseに更新可能/挿入可能に設定する必要があり、私のJavaエンティティの自動インクリメント数、ビーイング更新できません。タイムスタンプ列ここ

は私のJavaのエンティティのマッピングです:

@Version 
@Column(name = "TSROWVERSION", insertable = false, updatable = false) 
private byte[] version; 

私はこのSレコードを更新するときQLが実行されます。

(1) *SELECT ... FROM cmd_e_entities WHERE uidentity=?* 

(2) *UPDATE cmd_e_entities SET... WHERE uidentity=?* 

が、私のような何かを得るために期待していた:レコードが変更された場合

(3) *UPDATE cmd_e_entities SET... WHERE uidentity=? AND tsrowversion=?* 

Hibernateがチェックする最初のSELECTを実行し(1)、およびそれが更新されます(2) 。レコードが変更された場合は、例外がスローされます:

org.hibernate.StaleObjectStateException:行が別のトランザクションによって

を更新または削除されましたので、に取るために、それは正常に動作しますが、私はUPDATEを期待していましたバージョン(3)を考慮する。実際には、SQLタイプをTIMESTAMPからNUMBERに変更し、insertable/updatebleを削除すると、期待通りに機能します。

UPDATEがバージョン(... AND tsrowversion=?)を考慮していない場合、どのように楽観的なロックを保証できますか?どうすれば期待通りの行動を取ることができますか?

答えて

0

Hibernateは、メモリ内のエンティティのバージョンが永続化されたものと同じであることをチェックします。エンティティのIDは変更されませんが、Hibernateはエンティティの1つのバージョンのみを保持しているので、バージョンの列をフィルタリングする必要はありません。 多分このJPA and optimistic locking modesが助けてくれるかもしれない