わかりました。シングルトンで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はシングルトンでなければならないのですか?私は並行性の問題がありますが、マルチスレッドグラマーの経験がないため、このアイデアを明確にすることはできません。
EntityManagerFactoryインスタンスは重量級のオブジェクトです。各ファクトリは、メタデータキャッシュ、オブジェクト状態キャッシュ、EntityManagerプール、接続プールなどを維持する場合があります。アプリケーションでEntityManagerFactoryが不要になった場合は、アプリケーションを閉じてこれらのリソースを解放する必要があります。
EntityManagerFactoryが閉じると、そのファクトリのすべてのEntityManager、ひいてはそれらのEntityManagerによって管理されているすべてのエンティティが無効になります。
新しい工場を繰り返し作成して閉鎖するよりも、工場を長期間開いたままにしておく方がはるかに優れています。したがって、ほとんどのアプリケーションはファクトリを閉じることはなく、アプリケーションが終了するときにのみファクトリを閉じます。
異なる構成の複数のファクトリを必要とするアプリケーションのみが、複数のEntityManagerFactoryインスタンスを作成して閉じる明確な理由があります。
デプロイされた永続ユニット構成ごとに作成できるEntityManagerFactoryは1つだけです。特定のファクトリから任意の数のEntityManagerインスタンスを作成できます。