27

Ok, I read bunch of articles/examples how to write Entity Manager Factory in singleton.

One of them easiest for me to understand a bit:

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

I learned that EntityManagerFactory (EMF) should only be created once preferably in application scope.

And also make sure to close the EMF once it's used (?)

So I wrote EMF helper class for business methods to use:

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

And my method using 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();
    }

I made sure to close EntityManager (em) within method level as suggested. But when should EntityManagerFactory be closed then? And why EMF has to be singleton so bad??? I read about concurrency issues but as I am not experienced multi-thread-grammer, I can't really be clear on this idea.

4

1 回答 1

62
  • EntityManagerFactory 实例是重量级对象。每个工厂都可能维护一个元数据缓存、对象状态缓存、EntityManager 池、连接池等。如果您的应用程序不再需要 EntityManagerFactory,您应该关闭它以释放这些资源。

  • 当 EntityManagerFactory 关闭时,该工厂中的所有 EntityManager 以及由这些 EntityManager 管理的所有实体都将变为无效。

  • 长期保持工厂开工比反复创建和关闭新工厂要好得多。因此,大多数应用程序永远不会关闭工厂,或者仅在应用程序退出时关闭它。

  • 只有需要具有不同配置的多个工厂的应用程序才有明显的理由创建和关闭多个 EntityManagerFactory 实例。

  • 每个部署的持久性单元配置只允许创建一个 EntityManagerFactory。可以从给定的工厂创建任意数量的 EntityManager 实例。

  • JVM 中可能同时提供多个实体管理器工厂实例。EntityManagerFactory 接口的方法是线程安全的。
于 2010-12-28T06:13:37.910 回答