web-dev-qa-db-ja.com

EntityManagerFactoryインスタンスはいつ作成/開く必要がありますか?

わかりました。シングルトンでEntityManagerFactoryを作成する方法についての記事や例をたくさん読みました。

私が少し理解するのが最も簡単なものの1つ:

http://javanotepad.blogspot.com/2007/05/jpa-entitymanagerfactory-in-web.html

EntityManagerFactory(EMF)は、できればアプリケーションスコープで一度だけ作成する必要があることを学びました。

また、使用後は必ずEMF)を閉じてください(?)

そこで、私はEMFビジネスメソッドが使用するヘルパークラスを作成しました:

public class EmProvider {

    private static final String DB_PU = "KogaAlphaPU";

    public static final boolean DEBUG = true;

    private static final EmProvider singleton = new EmProvider();

    private EntityManagerFactory emf;

    private EmProvider() {}

    public static EmProvider getInstance() {
        return singleton;
    }


    public EntityManagerFactory getEntityManagerFactory() {
        if(emf == null) {
            emf = Persistence.createEntityManagerFactory(DB_PU);
        }
        if(DEBUG) {
            System.out.println("factory created on: " + new Date());
        }
        return emf;
    }

    public void closeEmf() {
        if(emf.isOpen() || emf != null) {
            emf.close();
        }
        emf = null;
        if(DEBUG) {
            System.out.println("EMF closed at: " + new Date());
        }
    }

}//end class

そしてEmProviderを使用する私の方法:

public String foo() {
    EntityManager em = null;
    List<Object[]> out = null;
    try {

        em = EmProvider.getInstance().getEntityManagerFactory().createEntityManager();
        Query query = em.createNativeQuery(JPQL_JOIN); //just some random query 
        out = query.getResultList();
    }
    catch(Exception e) {
        //handle error....
    }
    finally {
        if(em != null) {
             em.close(); //make sure to close EntityManager
        }
        //should I not close the EMF itself here?????
        EmProvider.getInstance().closeEmf();
    }

提案されているように、メソッドレベル内でEntityManager(em)を閉じるようにしました。しかし、EntityManagerFactoryをいつ閉じる必要がありますか?そしてなぜEMFはシングルトンでなければならないのですか?私は並行性の問題がありますが、マルチスレッドグラマーの経験がないため、このアイデアを明確にすることはできません。

24
Meow
  • EntityManagerFactoryインスタンスは重量級のオブジェクトです。各ファクトリは、メタデータキャッシュ、オブジェクト状態キャッシュ、EntityManagerプール、接続プールなどを維持する場合があります。アプリケーションでEntityManagerFactoryが不要になった場合は、アプリケーションを閉じてこれらのリソースを解放する必要があります。

  • EntityManagerFactoryが閉じると、そのファクトリのすべてのEntityManager、ひいてはそれらのEntityManagerによって管理されているすべてのエンティティが無効になります。

  • 新しい工場を繰り返し作成して閉鎖するよりも、工場を長期間開いたままにしておく方がはるかに優れています。したがって、ほとんどのアプリケーションはファクトリを閉じることはなく、アプリケーションが終了するときにのみファクトリを閉じます。

  • 異なる構成の複数のファクトリを必要とするアプリケーションのみが、複数のEntityManagerFactoryインスタンスを作成して閉じる明確な理由があります。

  • デプロイされた永続ユニット構成ごとに作成できるEntityManagerFactoryは1つだけです。特定のファクトリから任意の数のEntityManagerインスタンスを作成できます。

  • JVMでは、複数のエンティティマネージャファクトリインスタンスを同時に使用できる場合があります。 EntityManagerFactoryインターフェースのメソッドはスレッドセーフです。
58
Nayan Wadekar