2011-12-23 8 views
6

DAOのインスタンスごとにjavax.persistence.EntityManagerのインスタンスを使用した過去にいくつかのJPAを構築しました。これはほとんどの例が設定されている方法です。JPA EntityManagerスタティックまたはインスタンス?

public class BaseDaoThatEveryDaoExtends { 
    @PersistenceContext 
    private EntityManager entityManager; 
} 

私はちょうどPersistenceContext注釈によって注入静的javax.peristence.EntityMangerを使用するコードにつまずいてきた、建築家は、これは問題ないし、彼らもJTAとANとクラスタ化されたアプリケーション内の任意の問題があったことがない私に語りましたXAデータソース:EntityManagerは、いくつかの状態情報を保持し、それが静的作ることは、全体の状態のアプリケーション広いことになり限り、私はこれを言うことができるように

public class BaseDaoThatEveryDaoExtends { 
    @PersistenceContext 
    private static EntityManager entityManager; 
} 

はアンチパターンです。また、これにより、クラスを非常にテストするのが難しくなります。

これには他にも欠点がありますか、これはEntityManagerを使用する標準的な方法ですか?

答えて

1

EntityManagerは、スレッドローカルを使用してそのデータを保持しているため、スレッドにアクセスするすべてのスレッドが独立して処理されるため、静的な参照を保持することができます。実際、シングルトンパターンを使用して静的な方法でEJBコンテキストがEntityManagerに保持されている場合、私は驚くことはありません。

個人的には決して静的な方法で定義しません。それは不要と思われ、最悪の場合、予期せぬ副作用が生じるかもしれません。私が見ることができる

一つの問題は、誤って静的メソッドからEntityManagerをアクセスする能力である。

public class BaseDaoThatEveryDaoExtends { 
    @PersistenceContext 
    private static EntityManager entityManager; 

    public static void doSomeStaticWork(){ 
     ... 
     entityManager.doSomething; //NPE possible! 
    } 
} 

私のEntityManagerを注入し、この場合のNPEに得られていない見ることができます。

これ以外に、EntityManagerを使用したテスト/モックに関するいくつかの問題がある可能性があります。

+0

NPEは、手動でDAOのインスタンスを作成する代わりに手動で作成し、インスタンスメソッドをインボークするときにも、可能です。だからそれは本当の議論ではない。 – BalusC

+0

BaseDaoThatEveryDaoExtendsを構築する必要がないことを除いて、BaseDaoThatEveryDaoExtends.doSomeStaticwork()を呼び出してNPEを呼び出すことができます。 –

0

EntityManagerFactoryはスレッドセーフであることが保証されているので、これは「正しい」方法です。 スレッド非安全な場所でEMFを使用し、EntityManger自体をスレッドの問題から保護します。

4

私は主なリスクはEntityManager自体ではなく、エンティティマネージャが使用されたときにエンティティマネージャにアタッチされているアプリケーションコンテキストにあると思います。

2つの異なるクライアントがアプリケーションに2つの異なるメソッドを呼び出す(両方とも異なるスレッドで実行されますが、どちらも同じエンティティマネージャを使用しているとします)。

私が知っている限り、エンティティマネージャには単一のコンテキストが添付されていますが、このコンテキストは両方のクライアントによって共有されます。コンテキストにインスタンスをロードするたびに、共有エンティティ・マネージャを介してスレッドが使用できるようになります。互いのデータを改ざんするとどうなりますか?異なるトランザクション分離構成を使用している場合はどうなりますか。クライアント1が現在クライアント2によって使用されているデータを変更していないことを、どうすれば確実に確認できますか?

クライアントのいずれかがコンテキストを無効にした場合、他のクライアントはどうなりますか?このように並行処理をどうやって処理しますか?

関連する問題