Должен ли JPA Entity Manager быть закрыт?


У меня есть метод, приведенный ниже.

public Profile readUser(String email){
    EntityManager em = EMF.get().createEntityManager();
    return em.find(Profile.class, email);
}

выше использование entity manager в порядке? Или надо их закрыть?Любые предложения, пожалуйста.

1 67

1 ответ:

Я полагаю, ответ: зависит.

ваш менеджер сущностей является ключом для получения доступа к контексту, в котором находятся сущности. Если ваше приложение является Южная Африка, вы должны рассмотреть, какова продолжительность жизни ваших условиях.

давайте рассмотрим, что вы создадите entity manager по запросу пользователя. Таким образом, пока вы посещаете данный запрос, вы будете держать свой entity manager открытым, и когда вы закончите с ним, вы его закроете.

в приложении JSE вы, возможно, подумали, что вы хотели бы, чтобы ваш entity manager был открыт всю жизнь приложения (предположим, что вы не имеете дело с большими объемами данных), а затем вы закрываете его, когда ваше приложение завершает работу.

в итоге, когда вы открываете его, и когда вы полностью зависит от вашей стратегии и вашего дизайна. Вы закрываете его, когда вам больше не нужны сущности в его контексте.

в вашем примере это не так очевидно, но поскольку вы создаете EM в методе, вы должны закрыть его перед возвращением, иначе у вас больше не будет доступа к нему снова (если вы не держите его в каком-то реестре, что не видно в коде).

если вы не закроете его, ваши объекты будут храниться как прикрепленные, даже после того, как вы закончите их использовать. Ваш контекст будет сохранен, даже если вы больше не можете получить доступ к своим EM.

The спецификация JPA содержится больше подробности. В разделе 7.7 управляемые приложением контексты персистентности он говорит:

при использовании диспетчера объектов, управляемых приложением, приложение взаимодействует непосредственно с менеджером сущностей поставщика сохраняемости фабрика для управления жизненным циклом entity manager и получения и уничтожьте контексты персистентности.

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

The EntityManagerFactory.createEntityManager метод и EntityManagerclose и isOpen методы используются для управления жизненный цикл диспетчера объектов, управляемых приложением, и связанный с ним контекст персистентности.

расширенный контекст сохранения существует с точки, в которой entity manager был создан с помощью EntityManagerFactory.createEntityManager пока диспетчер сущностей не будет закрыто с помощью EntityManager.close.

расширенный контекст сохранения, полученный из управляемый приложением диспетчер сущностей-это автономное сохранение контексте не распространяется вместе с транзакцией.

[...] The EntityManager.close метод закрывает диспетчер сущностей для освободите его контекст сохранения и другие ресурсы. После вызова закройте, приложение не должно вызывать никаких дополнительных методов на EntityManager экземпляр, кроме getTransaction и isOpen, или элемент IllegalStateException будет брошен. Если метод close вызывается, когда транзакция активна сохранение контекста остается до завершения транзакции.

The EntityManager.isOpen метод указывает, является ли лицо Менеджер открыто. Элемент isOpen метод возвращает true, пока диспетчер сущностей не имеет был закрыт. Чтобы действительно понять, как это работает, жизненно важно понять отношения между менеджером сущностей и контекстом.

Итак, как вы можете видеть, Entity manager-это открытый интерфейс, через который вы получаете доступ к своим сущностям, однако ваши сущности находятся в контексте, прикрепленном к вашему менеджеру сущностей. Понимание жизненного цикла различных типов контекстов ответит на ваш вопрос.

контексты персистентности могут быть разных типов. В приложениях Java EE вы можете либо иметь контекст персистентности в области транзакций или расширенные-сохранение контекста. В приложении JSE характер контекста контролируется разработчик.

когда вы запрашиваете сущность для вашего менеджера сущностей, он ищет сущность в своем вложенном контексте, если он находит сущность там, то он возвращает ее, в противном случае он извлекает сущность из базы данных. Последующие вызовы этой сущности в контексте вернут ту же самую сущность.

операции в области

в приложении Java EE, использующем контекст персистентности в области транзакций, при первом доступе к вашему entity manager, он проверяет, имеет ли текущая транзакция JTA прикрепленный контекст, если контекст еще не присутствует, создается новый контекст, и Entity manager связан с этим контекстом. Затем объект считывается из базы данных (из кэша, если он присутствует) и он помещен в контекст. Когда ваша транзакция заканчивается (фиксация или откат), контекст становится недействительным, и все сущности в нем отсоединяются. Это классический сценарий для сеансов без сохранения состояния зернышки.

@PersistenceContext(unitName="EmplService")
EntityManager em;

это также означает, что в зависимости от того, как вы разрабатываете свои транзакции, вы можете получить более одного контекста.

Расширенные-Сохранение Контекста

в приложении Java EE с сеансовыми бобами с отслеживанием состояния вам может понравиться контекст, чтобы пережить несколько вызовов бобов, так как вам не понравится фиксировать, пока Боб не будет отмечен для удаления, верно? В этих случаях необходимо использовать расширенный контекст персистентности. В в этом случае контекст персистентности создается, когда он впервые необходим, но он не станет недействительным, пока вы не отметите statefull bean для удаления.

@PersistenceContext(unitName="EmplService", type=PersistenceContextType.EXTENDED)

это означает, что независимо от экземпляра Entity manager, который вводится в этот компонент при последующих вызовах методов statefull session beans, вы можете быть уверены, что всегда будете обращаться к одному и тому же контексту, и поэтому даже последующие вызовы будут возвращать один и тот же экземпляр, потому что это одно и то же контекст.

кроме того, ваши изменения не будут сброшены до тех пор, пока Боб не будет помечен для удаления или вы не сбросите их вручную.

Приложения, Управляемого

вы всегда можете создать экземпляр вручную вашей фабрики Entity manager и вашего Entity manager. Это то, что вы обычно делаете в приложении JSE, верно?

для такого рода приложений у вас обычно нет контейнера для обработки транзакций JTA, верно? Таким образом, вы используете локальные транзакции ресурсов и несете ответственность за ручное фиксацию или откат изменений.

для такого рода приложений при создании экземпляра Entity manager к нему автоматически присоединяется контекст.

в зависимости от вашего приложения, вы можете решить создать глобальный менеджер сущностей, жизненный цикл которого привязан к жизни самого приложения. То есть единый менеджер сущностей на весь срок службы приложения. В в этом случае контекст будет создан и уничтожен с помощью диспетчера сущностей.

или вы можете создать диспетчер сущностей для каждого разговора (т. е. транзакции) с вашим пользователем приложения. Область в этом случае определяется вами, но все же ваш контекст будет создан и уничтожен с помощью вашего entity manager.