2012-03-20 52 views
1

Hibernate 4.1.0が提供するSpring 3.1/JPA 2の使用。Hibernate/JPA @Versionと@GeneratedがStaleObjectStateExceptionの原因となる

基本的な監査機能(タイムスタンプ、バージョン番号の更新など)を提供するすべてのエンティティの基本クラスを用意しています。他のアプリケーションがデータベースにアクセスするため、これらはトリガーで設定する必要があります。そしてStaleObjectStateExceptionで結果 -

public abstract class AbstractBaseModel implements Serializable { 

@Version 
@Generated(GenerationTime.ALWAYS) 
@Column(name = "VERSION", insertable = false, updatable = false) 
protected Long version; 

@Generated(GenerationTime.ALWAYS) 
@Column(name = "UPDATE_TIMESTAMP", insertable = false, updatable = false) 
protected Date updateDate; 
... 
} 

org.hibernate.engine.internal.increment(...)メソッドは常にトランザクションをコミットするときに呼び出されます。

私のマッピングは次のようになります。

バージョンの列にGenerationTime.NEVERを設定しても不思議ではありませんが、hibernateはまだバージョンをインクリメントしますが、正しく維持されます。問題は、データベースのバージョンが更新されない場合(たとえテーブルに変更がない場合でも)、マージから返されたバージョンがデータベース値より1高くなり、後続のセーブで明らかに問題が発生することです。

GenerationTime.ALWAYSは、バージョンをインクリメントしてデータベースに依存せず、挿入/更新してから更新された値を選択することを決して避けたいと考えています。

どこの人が私の理解と実装に間違っているのか教えていただけますか?

答えて

0

あなたの実際の質問に対する回答はありませんが、私はあなたの問題の解決策を持っています。 :)休止状態で

は、これを行うには完全に有効です:

@Version 
@Temporal(TemporalType.TIMESTAMP) 
@Column(name = "UPDATE_TIMESTAMP" 
private Date updateDate; 

これは、あまりにも、あなたの更新日時バージョンになります。これは両方とも希薄であり、エンティティのマージのたびに自動的に更新されます。

ところで、私はメンバーを非公開にして、get tersとsetを追加することをお勧めします。

+0

ああ、あなたは私の問題を解決したが、悲しんではいけなかった。これは '@ Version'と' @ Generated'と同じ動作をします。フラッシュが発生する前に常にバージョンをインクリメントし、オプティミスティックロック例外を発生させます。私が望むのは、いつも '@ Generated'とマークされたフィールドを増やそうとしないことです。これはOracle固有の問題ですが、私は完全に困惑しています。 – Ben

+0

これは実際には本当に不思議です。このコードは、数ヶ月間、本番環境で問題なく実行されています。私はあなたを助けることができなかったことに非常に残念です、私は本当にあなたの問題を解決するだろうと思った... – LeChe

関連する問題