По сравнению с кодом из листинга 6.2 код, приведенный в листинге 6.3, намного проще. Во-первых, в нем нет Persistence или EntityManagerFactory, поскольку контейнер внедряет экземпляр EntityManager. Приложение не отвечает за управление жизненным циклом менеджера сущностей (создание или закрытие). Во-вторых, поскольку EJB-компоненты без сохранения состояния управляют транзакциями, в этом коде не указан явным образом параметр commit или rollback. Такой стиль EntityManager демонстрируется в главе 7.
Если вы заглянете в подраздел «Производители данных» главы 2, то поймете, что также можете использовать @Inject в сочетании с EntityManager, если будете генерировать его (с применением аннотации @Produces).
Контекст постоянства
Перед тем как подробно исследовать API-интерфейс менеджера сущностей, вам необходимо понять крайне важную концепцию:
Менеджер сущностей обновляет контекст постоянства или обращается к нему при каждом вызове метода интерфейса javax.persistence.EntityManager. Например, когда произойдет вызов метода persist(), сущность, передаваемая как аргумент, будет добавлена в контекст постоянства, если ее там еще нет. Аналогичным образом при поиске сущности по ее первичному ключу менеджер сущностей сначала проверяет, не содержится ли уже в контексте постоянства запрашиваемая сущность. Контекст постоянства можно рассматривать как кэш первого уровня. Это небольшое жизненное пространство, в котором менеджер сущностей размещает сущности перед тем, как сбрасывать содержимое в базу данных. По умолчанию объекты располагаются в контексте постоянства столько времени, сколько длится соответствующая транзакция.
Чтобы резюмировать все это, взглянем на рис. 6.1, где показано, что двум пользователям требуется доступ к сущностям, данные которых хранятся в базе данных. У каждого пользователя имеется собственный контекст постоянства, в котором все сохраняется, пока длится его транзакция. Пользователь 1 получает из базы данных сущности с идентификаторами 12 и 56, поэтому оба размещаются в его контексте постоянства. Пользователь 2 получает сущности с идентификаторами 12 и 34. Как вы можете видеть, сущность с идентификатором 12 располагается в контексте постоянства каждого из пользователей. Пока длится транзакция, контекст постоянства выступает в роли кэша первого уровня, где находятся сущности, которыми может управлять менеджер сущностей. Когда транзакция завершается, контекст постоянства очищается от сущностей.
Рис. 6.1. Сущности, которые располагаются в контексте постоянства разных пользователей
Конфигурация для менеджера сущностей привязывается к экземпляру EntityManagerFactory, который применяется для его создания. Независимо от того, является ли среда управляемой приложением или же контейнером, эта фабрика необходима как единица сохраняемости, с использованием которой будет создаваться менеджер сущностей. Единица сохраняемости обуславливает параметры для подключения к базе данных и список сущностей, которыми можно управлять в контексте постоянства. Файл persistence.xml (листинг 6.4), располагающийся в каталоге META-INF, определяет единицу сохраняемости, у которой есть имя (chapter06PU) и набор атрибутов.
·············xmlns: xsi="http://www.w3.org/2001/XMLSchema-instance"
·············xsi: schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
·············http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
·············version="2.1">
··
····
····
····