У меня есть способ ниже.
public Profile readUser(String email){
EntityManager em = EMF.get().createEntityManager();
return em.find(Profile.class, email);
}
Нормально ли вышеупомянутое использование диспетчера сущностей? Или необходимо закрыть их? Любые предложения, пожалуйста.
Ответы:
Я полагаю, ответ таков: это зависит от обстоятельств .
Ваш менеджер сущностей - ключ к получению доступа к контексту, в котором находятся сущности. Если ваше приложение является приложением JSE, вы должны учитывать ожидаемую продолжительность жизни вашего контекста.
Предположим, вы создадите диспетчер сущностей по запросу пользователя. Итак, пока вы обслуживаете данный запрос, вы будете держать свой менеджер сущностей открытым, а когда вы закончите с ним, вы его закроете.
В приложении JSE вы, возможно, считали, что хотите, чтобы диспетчер сущностей оставался открытым на протяжении всей жизни приложения (предположим, что вы не имеете дело с большими объемами данных), а затем закрываете его, когда приложение завершает работу.
Итог: когда вы его открываете и когда закрываете, полностью зависит от вашей стратегии и вашего дизайна. Вы закрываете его, когда вам больше не нужны сущности в его контексте.
В вашем примере это не очевидно, но поскольку вы создаете EM в методе, вы должны закрыть его перед возвратом, иначе у вас больше не будет к нему доступа (если вы не сохраните его в каком-то реестре, что не видно в коде).
Если вы не закроете его, ваши сущности будут оставаться прикрепленными даже после того, как вы закончите их использовать. Ваш контекст будет сохранен, даже если вы больше не сможете получить доступ к своему EM.
Спецификация JPA содержит больше деталей. В разделе 7.7 Контексты сохраняемости, управляемые приложением, говорится:
Итак, как вы можете видеть, диспетчер сущностей - это общедоступный интерфейс, через который вы получаете доступ к своим сущностям, однако ваши сущности находятся в контексте, прикрепленном к вашему диспетчеру сущностей. Понимание жизненного цикла различных типов контекстов ответит на ваш вопрос.
Контексты сохраняемости могут быть разных типов. В приложениях Java EE вы можете иметь либо контекст персистентности в области транзакции, либо контекст расширенного сохранения . В приложении JSE характер контекста контролируется разработчиком. .
Когда вы запрашиваете сущность у своего диспетчера сущностей, он ищет эту сущность в присоединенном контексте, если находит сущность там, то возвращает ее, в противном случае извлекает сущность из базы данных. Последующие вызовы этой сущности в контексте вернут ту же самую сущность.
В рамках транзакции
В приложении Java EE, использующем контекст персистентности в области транзакции, когда вы впервые обращаетесь к своему менеджеру сущностей, он проверяет, имеет ли текущая транзакция JTA присоединенный контекст, если контекст еще не присутствует, создается новый контекст и связывается менеджер сущностей. в этом контексте. Затем объект считывается из базы данных (o из кеша, если он есть), и помещается в контекст. Когда ваша транзакция завершается (фиксация или откат), контекст становится недействительным и все объекты в нем отсоединяются. Это классический сценарий для сессионных bean-компонентов без сохранения состояния.
@PersistenceContext(unitName="EmplService") EntityManager em;
Это также означает, что в зависимости от того, как вы разрабатываете свои транзакции, вы можете получить более одного контекста.
Контекст с расширенным постоянством
В приложении Java EE с сессионными bean-компонентами с отслеживанием состояния вам может потребоваться, чтобы контекст выдерживал многократные вызовы bean-компонентов, поскольку вам не нравится фиксировать, пока bean-компонент не будет отмечен для удаления, верно? В этих случаях вам нужно использовать расширенный контекст сохранения. В этом случае контекст сохранения создается, когда он впервые нужен, но он не станет недействительным, пока вы не отметите компонент с сохранением состояния для удаления.
@PersistenceContext(unitName="EmplService", type=PersistenceContextType.EXTENDED)
Это означает, что независимо от экземпляра диспетчера сущностей, который вводится в этот компонент при последующих вызовах методов сеансовых компонентов с сохранением состояния, вы можете быть уверены, что всегда будете обращаться к одному и тому же контексту, и, следовательно, даже последующие вызовы будут возвращать тот же самый например, потому что это тот же контекст.
Кроме того, ваши изменения не будут сброшены до тех пор, пока компонент не будет помечен для удаления или вы не очистите его вручную.
Управляемый приложением
Вы всегда можете вручную создать экземпляр фабрики диспетчера сущностей и диспетчера сущностей. Это то, что вы обычно делаете в приложении JSE, верно?
Для такого рода приложений у вас обычно нет контейнера для обработки транзакций JTA, верно? Таким образом, вы используете локальные для ресурсов транзакции и несете ответственность за ручную фиксацию или откат изменений.
Для этого типа приложений, когда вы создаете экземпляр своего менеджера сущностей, к нему автоматически присоединяется контекст.
В зависимости от вашего приложения вы можете решить создать глобальный менеджер сущностей, жизненный цикл которого привязан к жизни самого приложения. Это единый менеджер сущностей на все время существования приложения. В этом случае ваш контекст будет создан и уничтожен вашим менеджером сущностей.
Или вы можете создать диспетчер сущностей для каждого разговора (т. Е. Транзакции) с пользователем вашего приложения. В этом случае объем определяется вами, но все же ваш контекст будет создан и уничтожен вашим менеджером сущностей.
источник
EntityManager
должна быть незначительной. С моей точки зрения EntityManager - это просто абстракция для работы с единицей работы текущей транзакции. Я считаю, что создавать и уничтожать по одному за транзакцию - это нормально. Теперь это имеет другие последствия, потому чтоEntityManager
серверы в качестве кеша транзакций для ваших сущностей и, следовательно, с четко определенной областью транзакции и правильным взаимодействием с сущностями могут использовать преимущества этого кеша.