Чтобы действительно понять, как это работает, важно понять отношения между менеджером сущности и контекстом.
Менеджер сущностей - это общедоступный интерфейс, через который вы получаете доступ к вашим сущностям, однако ваши сущности находятся в контексте, связанном с вашим менеджером сущностей. Понимание жизненного цикла различных типов контекстов ответит на ваш вопрос.
Контексты постоянства могут быть разных типов. В приложениях Java EE вы можете иметь либо контекст персистентности в области транзакций , либо контекст расширенной персистентности . В приложении JSE природа контекста контролируется разработчиком .
Когда вы запрашиваете сущность у своего менеджера сущностей, она ищет сущность в своем прикрепленном контексте, если она находит там сущность, то возвращает ее, в противном случае она извлекает сущность из базы данных. Последующие вызовы для этой сущности в контексте вернут ту же сущность.
сделка в области видимости
В приложении Java EE, использующем контекст персистентности в области транзакций, когда вы впервые обращаетесь к своему диспетчеру сущностей, он проверяет, есть ли у текущей транзакции JTA контекст, к которому присоединен, если контекста еще нет, создается новый контекст и Менеджер сущностей связан с этим контекстом. Затем сущность считывается из базы данных (o из кэша, если имеется) и помещается в контекст. Когда ваша транзакция заканчивается (фиксация или откат), контекст становится недействительным, и все объекты в нем становятся отсоединенными. Это классический сценарий для сессионных компонентов без сохранения состояния.
@PersistenceContext(unitName="EmployeeService")
EntityManager em;
Это также означает, что в зависимости от того, как вы разрабатываете свои транзакции, вы можете получить более одного контекста.
Контекст расширенного постоянства
В приложении Java EE с сессионными компонентами statefull вам может понадобиться, чтобы контекст пережил несколько вызовов bean-компонентов, поскольку вам не захочется фиксировать их, пока компонент не будет помечен для удаления, верно? В этих случаях вам нужно использовать расширенный контекст постоянства. В этом случае контекст персистентности создается при первой необходимости, но он не станет недействительным до тех пор, пока вы не отметите бин Statefull для удаления.
@PersistenceContext(unitName="EmployeeService", type=PersistenceContextType.EXTENDED)
Это означает, что независимо от экземпляра диспетчера сущностей, который вводится в этот bean-компонент при последующих вызовах методов сессионных компонентов Statefull, вы можете быть уверены, что всегда будете иметь доступ к одному и тому же контексту, и, следовательно, даже последующие вызовы будут вернуть тот же экземпляр, потому что это тот же контекст.
Кроме того, ваши изменения не будут сбрасываться до тех пор, пока компонент не будет помечен для удаления или вы не сбросите их вручную.
Применение управляемого
Вы всегда можете создать экземпляр своей фабрики менеджера сущностей и менеджера сущностей. Это то, что вы обычно делаете в приложении JSE, верно?
Для таких приложений у вас обычно нет контейнера для транзакций JTA, верно? Таким образом, вы используете ресурсы локальных транзакций и несете ответственность за ручное принятие или откат изменений.
Для такого рода приложений, когда вы создаете экземпляр менеджера сущностей, к нему автоматически присоединяется контекст.
В зависимости от вашего приложения вы можете решить создать глобального менеджера сущностей, жизненный цикл которого привязан к жизни самого приложения. То есть один менеджер сущностей на всю жизнь приложения. В этом случае ваш контекст будет создан и уничтожен вашим менеджером сущностей.
Или вы можете создать менеджера сущностей для каждого разговора (то есть транзакции) с пользователем вашего приложения. Область действия в этом случае определяется вами, но ваш контекст будет создан и уничтожен вашим менеджером сущностей.