2013-10-11 12 views
11

を休止データベースに保存(更新)されます。私は、更新前metdhodでこれを行う:取得オブジェクトフィールド前の値の私は、このクラスを持っていると仮定しましょうJPA

@PreUpdate 
public void preUpdate(Object entity) { 
...some logic here...unable to get the old object value in here   
} 

だから私は名前と姓を持つMyClassオブジェクトインスタンス持つと仮定すると:私は聞いているので大丈夫です

MyClass mycls = new MyClass(); 
mycls.setName("Bob"); 
mycls.setSurname("Dylan"); 
mycls.save(); 

これは、リスナーによってピックアップされなかったが更新のみ。私はそうのように、このインスタンスを更新した場合 は今:

MyClass cls = MyClass.findById(someLongId) 
cls.setSurname("Marley"); 
cls.update(); 

だから、これはmylistenerでpreUpdate方法をトリガーし、私がしようとすると:私はすでに新しく更新されたインスタンスを取得デバッグする場合

MyClass.findById(someLongId); 

しかし、更新はまだ起こっていません。なぜなら、私がカラムの姓でデータベースをチェックインすると、それはまだDylanです。

preUpdateメソッドではデータベースからどのように値を取得できますか?今更新したものではありません。

答えて

18

JPAが保持しない一時変数に以前の値を保存するのが簡単な方法だと思います。 変数previousSurnameを導入し、セッターで上書きする前に実際の値を保存してください。

あなたは複数のプロパティを保存したい場合は、あなたのクラスMyClassSerializable.

であればそう

public class MyClass implements Serializable { 

    @Transient 
    private transient MyClass savedState; 

    @PostLoad 
    private void saveState(){ 
     this.savedState = SerializationUtils.clone(this); // from apache commons-lang 
    } 

} 

ポスト・ロード・リスナーを追加します。しかしsavedStateが分離されたインスタンスであることに注意している場合、それは簡単だろう。

あなたはEntityListenerの前の状態にアクセスできます。

PostLoadリスナーをEntityListenerクラスに移動することもできます。しかし、savedStateフィールドにアクセスする必要があります。私は

public class MyListener { 

    @PostLoad 
    private void saveState(MyClass myClass){ 
     myClass.saveState(SerializationUtils.clone(myClass)); // from apache commons-lang 
    } 

} 

public class MyClass implements Serializable { 

    @Transient 
    private transient MyClass savedState; 

    void saveState(MyClass savedState){ 
     this.savedState = savedState; 
    } 

} 
+0

こんにちはルネ、私は私のPOJOクラスで@PostLoadを持っていない、それはどちらかのパッケージがスコープ作るか、またはパッケージがアクセサをスコープと同じパッケージにMyClassMyListenerを入れて使用することをお勧めします。私はエンティティリスナの中に持っています –

+0

いいえ、エンティティリスナにコードを移動することができます。つまり、EntityListenerがロード時にオブジェクトのコピーを作成し、フィールドを設定するということです。それとも私が見逃していることはありますか? –

+0

このコードをリスナークラスに移動すると、リスナーのインスタンスが変更されます。ですから、ポストロードのリスナーインスタンスに値を設定すると、そのインスタンスはpreupdateでnullになります –