PersistenceUnit vs PersistenceContext
В нескольких проектах я успешно использовал
@PersistenceUnit(unitName = "MiddlewareJPA")
EntityManagerFactory emf;
...
EntityManager entityManager = emf.createEntityManager();
получить EntityManager
для подключения к базе данных, но несколько дней назад я пытался переместить мой проект на Jboss EAP 6.2
, и он не смог создать EntityManager
. Я искал его, и я обнаружил, что должен попробовать изменить @PersistenceUnit
на
@PersistenceContext(unitName = "MiddlewareJPA")
private EntityManager entityManager;
чтобы получить EntityManager. Это сработало, но я не знаю почему. В чем разница между PersistenceUnit
и PersistenceContext
? Каковы плюсы и минусы каждого из них? Где мы должны использовать один из них?
Ответы
Ответ 1
Я не знаю, как это работает именно в Java EE, но в Spring, когда вы указываете аннотацию @PersistenceContext
, она вводит EntityManager
. Где он получает EntityManager
? Неправильно создавать один EntityManager
для всего жизненного цикла приложения, вызывая EntityManagerFactory.createEntityManager()
. Поэтому вместо этого используется и реализуется специальная реализация интерфейса EntityManager
. Он имеет внутреннюю изменчивую нить-локальную ссылку на реальный EntityManager
. Реализации методов просто перенаправляют вызовы на этот реальный EntityManager
. И есть слушатель сервлета, который перед каждым запросом получает EM
, вызывая EMF.createEntityManager()
и назначая его этой внутренней ссылке специального EM
. Также этот прослушиватель управляет транзакциями, вызывая getTransaction().begin()
, .commit()
и .rollback()
на реальном EM
. Это очень упрощенное описание выполненной работы. И я считаю, что контейнер JEE делает то же самое, что и Spring.
В общем случае лучше вводить EntityManager
, потому что с EntityManagerFactory
и @PersistenceUnit
вы должны каждый раз создавать/уничтожать EntityManager
руками и управлять транзакциями тоже.
Ответ 2
PersistenceUnit
вводит EntityManagerFactory
, а PersistenceContext
вводит EntityManager
. Обычно лучше использовать PersistenceContext
, если вам действительно не нужно управлять жизненным циклом EntityManager
вручную.
Ответ 3
EntityManagers получают через @PersistenceContext Менеджер управляемых контейнеров, поскольку контейнер будет отвечать за управление "Управление Entity", а EntityManagers - через @PersistenceUnit/entityManagerFactory. createEntityManager() - это менеджер управляемых приложений, а разработчик должен управлять некоторыми вещами в коде (например, для освобождения ресурсов, полученных EntityManager).