如何在jpa中共享EntityManagerFactory

时间:2014-03-25 08:22:02

标签: java jpa

我是jpa的新手这是场景......我正在开发一个Web应用程序......其中

多个用户可以登录...

当user1 LogOut ...我正在使用下面的代码...

public static void closeEntityManagerFactory() {

    if (!entityManager.getTransaction().isActive()){

    entityManager.getTransaction().begin();

    }

    entityManager.close();

    emf.close();

}

即使user2被插入其中,也会抛出错误,告知实体管理器已关闭....

问题是我们不应该在应用程序启动后关闭EntityManager ...... ???或者我们

应该使用多个实例...如果是,如何实现这个...帮助将是明显的:):)

1 个答案:

答案 0 :(得分:4)

EntityManagerFactory实例创建起来很昂贵,而EntityManager实例则不然。 在Java SE Web应用程序中,大多数情况只能使用一个EntityManagerFactory实例进行处理。

您可以在ServletContextListenercontextInitialized方法中初始化EntityManagerFactory,并将该实例存储在上下文属性(context.setAttribute(key, emf))中:

public class CustomServletContextListener implements ServletContextListener {

    private EntityManagerFactory entityManagerFactory;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext context = sce.getServletContext();

        entityManagerFactory = Persistence.createEntityManagerFactory("UnitName");
        context.setAttribute("someKey", entityManagerFactory);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        /* Some method that cleanly destroys
         * your entity manager factory */
        closeEntityManagerFactory();
    }
}

稍后,您可以使用context.getAttribute("someKey")检索EntityManagerFactory实例,并在需要时创建EntityManager实例。

最后,为了使您的ServerContextListener实现正常工作,只需在web.xml中注册它:

<listener>
        <listener-class>com.company.listeners.CustomServletContextListener</listener-class>
</listener>

注意:是否需要短期或长期存在的EntityManager实例取决于应用程序的范围。在典型的Web应用程序中,跨越请求的短期应用程序更为明智。有关EntityManager实例的不同策略,请参阅Bauer和King,Manning的 Java Persistence with Hibernate 。该文本同时解决了Hibernate和JPA。