1

JPAが古いデータをキャッシュに保持することに問題があり、見つけた解決策を試しましたが、ポップアップし続けます!

とにかく、最初は効率のために 1 つの Entity Manager インスタンスを再利用しました。説明されている問題に初めて遭遇したとき、トランザクションごとに新しいエンティティ マネージャーが作成されるようにコードを変更しました。

/** This method is called every time a transaction is made. */

public static EntityManager createFreshEntityManager() {
    try {
        return Persistence.createEntityManagerFactory(puName)
                          .createEntityManager();         
    } 
    catch (Exception e) {
        logStuff(e); 
        return null;
    }
}

ただし、これで問題が解決するわけではありません。

JDBC を使用してテーブルを切り捨て、主キーをリセットすると、特定の新しく作成されたオブジェクトに古い変数値が含まれていることがよくあります。私が持っている疑いの 1 つは、主キーをリセットすることが原因である可能性があるということですが、繰り返しになりますが、トランザクションごとに新しい Entity Manager が既にあるため、まったく問題にはなりません。

DB エンティティが関数スコープ外のアプリケーションに格納されることはなく、必要に応じて常に DB から直接クエリが実行されるため、コードの問題ではないと確信しています。

EntityManager.clear() の使用についても読んだことがありますが、マルチスレッド プログラムを台無しにする可能性があるため、それほど残忍なことはしたくありません。

JDBC の代わりに JPA を使用して TRUNCATE を実行し、すべてのオブジェクトを一度に取得してから手動で 1 つずつ削除することを考えましたが、それは非効率的です... しかし、それでもボトルネックにはなりません。ただし、JDBCを使用してそれを行うことで違いが生じるかどうかはわかりません。

4

1 に答える 1

2

トランザクションごとに新しい EntityManager を作成する理由はありません。

@PersistenceContextを使用してEntityManagerを注入できるはずです。

次のようになります。

@Stateless
class SomeSessionBean implements SomeSessionBeanLocal {

    @PersistenceContext(unitName = "somePuName")
    private EntityManager em;

    public Customer findCustomerById(Long someId) {
        return em.find(Customer.class, someId);
    }
}

依存性注入にアノテーションを使用することは、EJB 3 の最大の特長の 1 つです。


問題の考えられる原因:

JavaEE Web アプリケーションの実行中にデータベースの値を変更した場合、その変更は EJB によってすぐには検出されない可能性があります。パーシステンス レイヤーはおそらくキャッシュを使用しています。

データベースの変更を「外部的に」行った後、おそらく webapp を再起動する必要があります。

于 2012-08-31T00:04:28.823 に答える