Лучшая практика для получения EntityManagerFactory

Как лучше всего получить EntityManagerFactory в веб-приложении (jsp/servlets)? Это хороший способ Когда следует создавать/открывать экземпляр EntityManagerFactory? , или лучше получить его от JNDI, или что-то еще?


person Evgeni Dimitrov    schedule 22.10.2011    source источник


Ответы (1)


Они тяжеловесны и должны входить в область применения. Таким образом, вам нужно открывать их при запуске приложения и закрывать при завершении работы приложения.

Как это сделать, зависит от вашего целевого контейнера. Поддерживает ли он EJB 3.x (Glassfish, JBoss AS и т. д.)? Если это так, то вам вообще не нужно беспокоиться об их открытии/закрытии (а также о транзакциях), если вы просто выполняете задание JPA в EJB с помощью @PersistenceContext обычным способом:

@Stateless
public class FooService {

    @PersistenceContext
    private EntityManager em;

    public Foo find(Long id) {
        return em.find(Foo.class, id);
    }

    // ...
}

Если ваш целевой контейнер не поддерживает EJB (например, Tomcat, Jetty и т. д.) и дополнение EJB, например OpenEJB также по какой-то причине не вариант, и поэтому вы вручную возитесь с созданием EntityManagers (и транзакций) самостоятельно, тогда ваш лучший выбор - ServletContextListener. Вот основной пример начала:

@WebListener
public class EMF implements ServletContextListener {

    private static EntityManagerFactory emf;

    @Override
    public void contextInitialized(ServletContextEvent event) {
        emf = Persistence.createEntityManagerFactory("unitname");
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        emf.close();
    }

    public static EntityManager createEntityManager() {
        if (emf == null) {
            throw new IllegalStateException("Context is not initialized yet.");
        }

        return emf.createEntityManager();
    }

}

(примечание: до Servlet 3.0 этот класс должен быть зарегистрирован <listener> в web.xml вместо @WebListener)

Что можно использовать как:

EntityManager em = EMF.createEntityManager();
// ...
person BalusC    schedule 22.10.2011
comment
Отличный пример, как всегда, но просто хотел добавить, что при использовании @PersistenceContext без атрибута unitName это подразумевает (недекларативным способом) использование единственного/по умолчанию модуля сохранения, определенного в файле persistence.xml. Если имеется несколько источников данных/единиц постоянства, это может привести к некоторой путанице в отношении того, какой из них это. - person Darrell Teague; 26.02.2013
comment
Не уверен, чего еще не хватает, я следую вашему ответу, но есть ошибка времени выполнения? › Вызвано: org.springframework.beans.factory.NoSuchBeanDefinitionException: не определен уникальный bean-компонент типа [javax.persistence.EntityManagerFactory]: ожидается один bean-компонент, но найдено 0: - person huahsin68; 23.10.2013
comment
@ huahsin68: первоначальный вопрос вообще не касается Spring, и я тоже не использую Spring. Просто нажмите Задать вопрос. - person BalusC; 23.10.2013
comment
Не могли бы вы дать полное название класса Persistence? - person Jarekczek; 01.04.2017