2016-10-29 17 views
2

私はそのように(Eclipselinkを使って)期待していなかったJPAの動作に困惑しています。JPA find()メソッドのコミットされていない変更を読み取らなかったのはなぜですか?

私はWildfly 10(JDK-8)でステートレスセッションEJB(3.2)を実行します。私のメソッド呼び出しは、デフォルトでは、トランザクション内にカプセル化されています。 私のビジネスメソッドは、エンティティBeanを読み込んで更新するときに、特にエンティティのバージョン番号などの更新を認識しませんでした。だから、

org.eclipse.persistence.exceptions.OptimisticLockException 

私のコードで私の呼び出しの結果はこのように簡略化になります。私は

でアノテート方法で(エンティティBeanのデータを変更し、フラッシュ)のコードを入れた場合

public ItemCollection process(MyData workitem) { 

    .... 
    // load document from jpa 
    persistedDocument = manager.find(Document.class, id); 
    logger.info("@version=" + persistedDocument.getVersion()); 
    // prints e.g. 3 

    // change some data 
    .... 
    manager.flush(); 
    logger.info("@version=" + persistedDocument.getVersion()); 
    // prints e.g. 4 

    .... 
    // load document from jpa once again 
    persistedDocument = manager.find(Document.class, id); 

    logger.info("@version=" + persistedDocument.getVersion()); 
    // prints e.g. 3 (!!) 

    // change some data 
    .... 
    manager.flush(); 
    // Throws OptimisticLockException !! 
    // [email protected]] cannot be updated because it has changed or been deleted since it was last read 

    ... 
} 

@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW) 

すべて正常に動作します。

しかし、なぜ私のコード内のfind()メソッドの2番目の呼び出しが新しいバージョン番号を読み取っていないのですか?私はflush()とfind()の呼び出しの後でバージョン4を期待しています。それは問題を解決

manager.clear(); 
を呼び出すように見える結局のところ

+0

同じトランザクションで2番目の呼び出し? –

+0

はいこれはすべて1つの同じステートレスセッションEJBメソッドで実行されます – Ralph

+0

私は別のプロジェクトでも同様のコードを持っていたと思いますが、多くのOneToMany関係を持っています。 – Ralph

答えて

2

。オブジェクトを切り離すと同じことをする必要があると思ったが、私の場合はclear()を呼び出すだけで問題が解決された。

その他の調査結果:

は、すべての後に、方法がデタッチ呼び出し()およびフラッシュ()サービス層を形成するのは良い考えではないようです。このidをクライアントに返すビジネスメソッドを残す前に、自分のエンティティの新しいバージョンIDを取得したかったので、これを行いました。私はこの場合の戦略を変更し、エンティティBeanを切り離してフラッシュすることですべての「悪いもの」を削除しました。コードはより明確になり、結局コードの複雑さは劇的に減少しました。

もちろん、entityManagerが正しく動作するようになりました。 1つのトランザクションで同じエンティティBeanに何度も再度照会すると、entityManagerは正しい更新バージョンを返します。

私自身の質問への答えは、メソッドflush()とclear()のままにしておき、実際に使用する理由がない限りです。

関連する問題