应该何时创建/打开EntityManagerFactory实例?

时间:2010-12-28 05:46:40

标签: java jpa singleton entitymanager

好的,我阅读了一些文章/示例如何以单身形式编写实体经理工厂。

其中一个对我来说最容易理解:

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必须单身这么糟糕?我读到了并发问题,但由于我没有经验丰富的多线程语法,我对这个想法并不是很清楚。

1 个答案:

答案 0 :(得分:56)

  • EntityManagerFactory实例是 重量级的物体。每个工厂 可能会维护元数据缓存, 对象状态缓存,EntityManager 池,连接池等。如果 你的申请不再需要了 你应该是EntityManagerFactory 关闭它以释放这些资源。

  • 当EntityManagerFactory关闭时, 该工厂的所有EntityManagers, 并且通过扩展来管理所有实体 由那些EntityManagers,成为 无效。

  • 保持工厂要好得多 打开很长一段时间 反复创建和关闭新的 工厂。因此,大多数应用 永远不会关闭工厂,或只关闭工厂 申请时关闭它 离开。

  • 仅限需要的应用程序 多个工厂有不同 配置有一个明显的原因 创建和关闭多个 EntityManagerFactory实例。

  • 只有一个EntityManagerFactory 允许为每个人创建 部署持久性单元 组态。任意数量的 EntityManager实例可能是 从给定的工厂创建。

  • 多个实体经理工厂 实例可能可用 同时在JVM中。 EntityManagerFactory的方法 接口是线程安全的。