Типы Entity Manager

advertisement
Entity Manager
1
Обзор
Архитектура Java Persistence API
Entity manager и Persistence Context
Persistence Provider и Entity Manager Factory
Типы Entity Manager
 Transaction-Scoped Entity Manager
 Extended Entity Manager
 Application-Managed Entity Manager
 Управление транзакциями
 Resource-Local транзакции
 Выбор Entity manager




Обзор
 Операции Entity Manager
 Сохранение сущности
 Поиск сущности
 Удаление сущности
 Каскадные операции
 Синхронизация с БД
 Detached сущности
 Merging
 Работа с detached сущностями
 Решение проблемы доступа к lazy атрибутам
detached сущности
 Стратегии слияния
Архитектура Java Persistence API
4
Entity manager и Persistence Context
 Entity Manager – API для создания, чтения, записи и
удаления сущностей из БД
 API инкапсулирован в интерфейсе EntityManager
 Managed сущность – это сущность, которую создал или
получил Entity Manager
 Набор сущностей, managed данным Entity Manager’ом в
данное время называется persistence context этого
Entity Manager
 Только одна сущность данного типа с одинаковым
идентификатором может содержаться в persistence
context
5
Persistence Provider и Entity Manager Factory
 Persistence Provider определяет конкретную
имплементацию интерфейса Entity Manager
 Отвечает за все обязанности Entity Manager:
генерацию SQL, обработку JPQL и т.д.
 Entity Manager’ы создаются и конфигурируются
фабрикой EntityManagerFactory
 XML конфигурация данной EntityManagerFactory
называется persistence unit
6
Persistence Provider и Entity Manager Factory
 Persistence unit определяет такие параметры как:
 Persistence Provider
 Тип Entity Manager
 Сущности, с которыми может работать Entity Manager
данного persistence unit
 Базу данных, с которой работает данный EM
 Прочие настройки
 Persistence unit именован, чтобы различать Entity Manager’ов,
созданных разными фабриками
 Одна фабрика может создавать несколько Entity Manager’ов
 Набор persistence unit’ов данного приложения образует файл
META-INF/persistence.xml
7
Persistence Provider и Entity Manager Factory
 Persistence unit определяет такие параметры как:
 Persistence Provider
 Тип Entity Manager
 Сущности, с которыми может работать Entity Manager
данного persistence unit
 Базу данных, с которой работает данный EM
 Прочие настройки
 Persistence unit именован, чтобы различать Entity Manager’ов,
созданных разными фабриками
 Одна фабрика может создавать несколько Entity Manager’ов
 Набор persistence unit’ов данного приложения образует файл
META-INF/persistence.xml
8
Типы Entity Manager
 Entity Manager и Persistence Context тесно связаны, хотя
PC не является частью API. Приложение никогда не
работает с PC
 Существует 3 типа Entity Manager. Каждый
взаимодействует с PC по-разному:
 Container-Managed (Transaction Scoped) EM
 Container-Managed (Extended) EM
 Application-Managed EM
 Понимание совместной работы EM данного типа с PC
критично в изучении JPA
9
Container-Managed Entity Manager
 EM, жизненным циклом которого управляет контейнер,
называется Container-Managed Entity Manager
(CMEM)
 В зависимости от способа работы EM с PC выделяют два
подтипа:
 Transaction-Scoped Entity Manager (TSEM)
 Extended Entity Manager (EEM)
 Для получения ссылки на любой CMEM служит аннотация
@PersistenceContext
 Схема работы CMEM зависит от JPA транзакции
10
Transaction-Scoped Entity Manager
 Когда над EM совершается некоторая операция (find, add,
etc), EM проверяет, ассоциирован ли PC с данной JPA
транзакцией
 Если PC ассоциирован с JTA, EM использует этот PC
 Если нет – EM создает пустой PC, ассоциирует его с
текущей JPA транзакцией и использует
 Когда транзакция завершается (commit), в БД изменяются
все сущности, отслеженные EM в данном PC
 После завершения транзакции (commit) PC разрушается
11
Extended Entity Manager
 Может использоваться только для stateful beans
 Detached сущность – это сущность, которая была
managed некоторым EM, но была удалена из PC
после его закрытия
 Определяется с помощью:
 @PersistenceContext(unitName="EmployeeService",
type=PersistenceContextType.EXTENDED)
 PC создается в момент создания stateful бина,
удаляется в момент его удаления
12
Extended Entity Manager
 В каждый момент завершения транзакции, все
изменения с предыдущей транзакции, проведенными
над сущностями PC, отслеженные EM уходят в базу.
 Разница с TSEM в том, что после завершения
транзакции PC не разрушается
 Extended EM экономит roundtrip в БД, хорош для
сервисов, которым необходима поддержка состояния
 Минус в том, что stateful бины не сильно
распространены
13
Application-Managed Entity Manager
 Приложение управляет
 созданием EM из фабрики
 управлением транзакциями
 закрытием EM
 PC создается немедленно после создания EM фабрикой и
длится до явного закрытия EM
 Пример. Application Managed EM в среде Java SE (example_05-01)
 Пример. Application Managed EM в среде Java EE (example_05-02)
14
Управление транзакциями
 Транзакция определяет когда новая, измененная или
удаленная сущность будет синхронизирована с БД
 JPA поддерживает 2 вида транзакций:
 Resource Local
 JTA
 Container-Manager EM могут работать только с JPA
 Application Managed EM могут работать с любым типом
транзакции
 Тип транзакции для данного persistence unit определяется
в persistence.xml для данного блока:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="EmployeeService" transactiontype="RESOURCE_LOCAL">
15
Управление JPA транзакциями. Определения
 Синхронизация транзакции (transaction
synchronization) – принцип, согласно которому PC
связывается с транзакцией
 Ассоциация транзакции (transaction association) –
акт (процесс) связывания PC с транзакцией
 Продление транзакции (transaction propagation) –
процесс начала совместного использования (sharing)
PC несколькими EM в пределах одной транзакции
16
Transaction-Scoped Persistence Context
 PC продляется так же, как продляется JPA транзакция
 После вызова метода, TSEM проверяет, есть ли
продленный PC
 Если нет, то создает его
 EM создает PC lazily, только если вызвана операция на EM
 Таким образом, различные части приложения (разные
бины) могут использовать один и тот же PC, если они
работают в одной транзакции, несмотря на то, что
используют разные экземпляры EM
 Пример. PC Propagation (example_05-03)
17
Extended Persistence Context
 Extended PC (PC1) создается в момент создания
stateful бина SFUL1
 Непосредственно (eager) в момент вызова stateful
бина (или части метода бина), работающего в
транзакции T1, PC1 ассоциируется с T1
 Даже если с T1 уже был ассоциирован контекст
PC0
 Весь последующий код, работающий в этой же
транзакции T1 будет использовать PC1
 Весь PC1 будет доступен в транзакции T1, которая
может его произвольно модифицировать

Пример. Extended PC (example_05-04)
18
Коллизия контекстов
 Предположим, что SFUL1 был вызван из stateless бина
SLESS1, который работал в транзакции T1 и имел
контекст PC0
 В момент вызова SFUL1 произойдет ассоциация (eager)
PC1 с T1
 Но PC0 уже продлен (propagated) с транзакцией T1
 Произойдет коллизия контекстов
 Может существовать только один активный PC в
данной транзакции
 Провайдер выбросит исключение
 Хорошо, когда stateful бин – первый в цепочке вызовов,
все последующие вызовы используют transaction scoped
PC
19
Как бороться с коллизией контекстов
 На stateful бине, определяющем extended PC:
 Использовать транзакционный атрибут REQUIRES_NEW
 Постоянное создание новых транзакций может
отрицательно сказаться на производительности
системы
 Использование разных транзакций может оказаться
логически неверным
 Использовать транзакционный атрибут NOT_SUPPORTED
 Может использоваться только если логика метода не
пересекается с вызывающей логикой и не требует
транзакции

Пример. Избегание коллизий (example_05-05)
20
Наследование persistence context’ов
 Если stateful бин (SB1) с extended PC (PC1) создает
другой stateful бин (SB2) с extended PC, то коллизии
не произойдет
 Вместо этого дочерний бин SB2 будет создан с
контекстом PC1
 Контекст унаследуется

Пример. Наследование контекстов (example_05-06)
21
Application-Managed Persistence Contexts
 Жизненный цикл application managed PC совпадает с
жизненным циклом application managed EM
 AM EM создается запросом фабрики и получением ссылки
на EM из фабрики
 Приложение ассоциирует AM PC с JTA транзакцией одним
из двух способов:
 EM создается в транзакции
 Вызовом em.joinTransaction()
22
Application-Managed Persistence Contexts
 AM EM не продляют (propagate) свой PC. Следствия:
 Поэтому не может быть коллизий контекстов
 Для того, чтобы share контекст с другими
компонентами, необходимо передавать EM
 С данной транзакцией можно ассоциировать
произвольное количество application managed PC
 Если PC синхронизирован с транзакцией, то изменения
будут записаны в БД, даже если соответствующий EM
будет закрыт

Пример. Наследование контекстов (example_05-07)
23
Resource-Local транзакции
 Resource-Local транзакции полностью управляются
приложением. Нет вмешательства Java EE сервера
 RL транзакция получается из application-managed EM
вызовом em.getTransaction()
 EntityTransaction имитирует JTA UserTransaction
24
Resource-Local транзакции
 Операции EntityTransaction определены через
транзакционные механизмы JDBC. Нет глобального (XA)
транзакционного поведения
 RL транзакция не зависит от JTA транзакции и может
commit или rollback без какого-либо влияния на JTA
 RL транзакция может использоваться для
логирования
 Пример. Наследование контекстов (example_05-08)
25
Rollback транзакции и состояние сущности
 Модель памяти Java не транзакционна
 Когда транзакция завершается (commit), PC смотрит на все
свои объекты, которые удалены, изменены или созданы и
генерирует SQL для обновления БД
 Выполнение этого SQL может прерваться (rollback).
Произойдет 2 вещи:
 Изменения в БД откатятся
 PC очистится, все managed сущности станут detached
 Произойдет рассинхранизация БД и detached объектов в
памяти
 Рассмотреть возможность сделать попытку второго
commit и выполнить слияние (merge) сущностей
26
Какой Entity manager использовать
 Для большинства Java EE приложений подойдет
Container-Managed Transaction-Scoped EM
 Таковой была имплементация многих коммерческих
ORM фреймворков (TopLink)
 Наиболее понятна семантика работы
 Идея Extended PC была введена впервые в JPA
 Есть performance плюсы
 Есть ограничения (коллизии)
27
Какой Entity manager использовать
 Использование Application-Managed PC в Java EE
средах не очень хорошая идея
 Нет context propagation
 Application-Managed PC Может отлично
использоваться в Java SE средах, а так же в custom
фреймворках
 Смешивать разные типы EM в архитектуре одного
приложения определенно плохая идея
28
Операции Entity Manager. Сохранение сущности
 Метод em.persist(e) принимает новую сущность и делает
ее managed
 Если е уже managed, ничего не происходит
 При вызове persist() данные не сохраняются в БД. Будут
сохранены при синхронизации PC с БД (commit, flush)
 При вызове persist() вне транзакции в transactionscoped EM, будет возбужден
TransactionRequiredException
 Однако, EM может теперь отслеживать все изменения
над Java экземпляром e
29
Операции Entity Manager. Сохранение сущности
 EntityExistException будет возбужден:
 При вызове persist(), если EM обнаружит, что сущность
с тем же идентификатором уже managed
 При commit в БД, если на уровне SQL обнаружится,
что сущность с тем же идентификатором уже
существует в БД
 Пример:
30
Операции Entity Manager. Поиск сущности
 em.find(key) выбирает сущность из БД или из PC
 Возвращенная сущность будет managed
 За исключением вызова find() вне транзакции в
transaction-scoped EM. В этом случае она будет
detached
31
Операции Entity Manager. Поиск сущности
 Когда target сущность в отношении one-to-one или many-toone существует в БД и ее ключ известен, нет нужды делать
SQL для выборки этой сущности
 getReference(key) возвращает прокси объект, в котором
определен только идентификатор сущности
 EntityNotFoundException будет возбужден при выхове
любого метода, кроме getID()
 Проксируемая сущность должна существовать в таблице
32
Операции Entity Manager. Удаление сущности
 em.remove(e) используется для удаления сущности e
 Данные реально удалятся из БД, при commit транзакции
 Обслуживание отношений выполняет приложение, не
JPA!
33
Операции Entity Manager. Удаление сущности
 Только для managed сущности может быть вызван em.remove()
 Вызов em.remove() вне транзакции
 в transaction-scoped EM приведет к
TransactionRequiredException
 В остальных типах EM ничего не произойдет:

Никакой exception не возбудится

Сущность не удалится из БД
34
Каскадные операции
 По умолчанию операция EM применяется только к сущности,
передаваемой в качестве аргумента. Не продолжается
(cascade) на другие сущности в отношении
 Это не ограничение спецификации. Приложение должно
иметь контроль над тем, что удаляется, что создается и т.д.
 В примере ниже разумно продолжать (cascade) операцию
persist автоматически при сохранении адреса
35
Cascade Persist
 Все каскадные установки однонаправленные
 Операция persist для managed сущности не имеет
никакого эффекта для этой сущности, но для ее
атрибутов выполнятся cascade persist операции
36
Cascade Remove
 Упоминалось о том, что это обязанность приложения занулять
ссылки. Ставить везде CascadeType.REMOVE не разумно
 Только в случае one-to-one и one-to-many можно
относительно безопасно использовать каскадное удаление
 При условии, что target сущности можно безопасно удалить
37
Синхронизация с БД
 PC сбрасывается (flush) каждый раз, когда
генерируется и исполняется SQL
 Flush происходит в двух случаях:
 Транзакция завершается (commit)
 Делается вызов em.flush()
 Провайдер может сделать flush в любой момент,
например:
 JPQL зависит от данных PC
 Flush происходит для сущностей:
 Новых
 Измененных
 Удаленных
38
Синхронизация с БД. Persist
 Flush новой сущности логически эквивалентен вызову
persist второй раз на этой сущности
39
Синхронизация с БД. Persist
 В общем виде, исключение будет возбуждено, если
managed сущность имеет ссылки на не-managed
сущности:
 Detached сущность
 Новая сущность
 Исключение из этого правила:
 Detached сущность является target сущностью one-toone или many-to-one отношения
 Новая сущность имеет каскадный атрибут
CascadeType.PERSIST
 В идеале, при persist весь граф объектов должен
быть managed
40
Синхронизация с БД. Remove
 Удаляется сущность:
 Так как flush в БД может произойти в любое время,
мы должны как можно раньше обеспечить
необходимые зануления foreign ключей source
сущностей
 Другими словами, занулить все отношения,
которые ссылаются на удаляемую сущность
 Непонимание этого факта может приводить к
мистически, плавающим ошибкам
41
Detached сущности
 Существует несколько причин, по которым сущность
может стать detached:
 транзакция в transaction-scoped EM commit, PC
разрушается
 application-managed PC закрывается
 stateful бин с extended PC удаляется (метод @Remove)
 вызван clear() метод у EM
 когда происходит rollback, все сущности в PC
становятся detached
 когда сущность сериализуется, она отсоединяется от
PC
42
Detached и Managed сущности
 У managed сущности мы можем вызвать любой lazy
атрибут. JPA сделает SQL вызов и выберет нужную
информацию из БД
 Lazy-loaded атрибуты detached сущности, к которым не
было вызова в момент, когда сущность еще была
managed представляют проблему. Спецификация JPA не
определяет поведение провайдера в этом случае.
Варианты:
 Провайдер все же постарается подгрузить сущность
 Сущность останется не проинициализированной
 Выкинет исключение
43
Пример. Lazy fetch Detached сущности
44
Detachment и merging
 Никакие программные изменения над detached сущностью
не будут commit в БД, т.к. EM не отслеживает эту
сущность
 Слияние (merge) это процесс обратной интеграции
detached сущности в EM
 Возможно offline изменение сущности (возможно в другой
JVM) с последующим слиянием этой сущности в EM и
commit в БД
45
Merge detached сущностей
 Метод E1=em.merge(E) делает merge detached сущности
E обратно в PC
 Сущность E не станет managed, ею будет E1!!!
46
Merge detached сущностей
 Если X является detached сущностью, состояние X
скопируется в уже существующую managed сущность X' с
тем же идентификатором, либо создается новая managed
сущность X'
 Если X это новая сущность, то создается новая managed
сущность X' и состояние X копируется в X'
 Если X это удаленная сущность, исключение
IllegalArgumentException будет возбуждено (либо
транзакция откатиться)
47
Merge detached сущностей
 Если X это managed сущность, она игнорируется, однако,
операция merge будет cascade на другие отношения из X,
если эти отношения аннотированы cascade атрибутами
cascade=MERGE or cascade=ALL
 Для всех сущностей Y на которые ссылается X и имеющих
cascade атрибут cascade=MERGE или cascade=ALL, Y
merge рекурсивно как Y'. Для каждой такой Y на которую
ссылается X, X' будет ссылаться на Y'
 EM не будет merge атрибуты, помеченные как lazy, если к
ним не было доступа, когда X была managed
 Если к lazy атрибуту A был доступ, когда X была managed
(атрибут был подгружен), после чего A был занулен,
атрибут А будет занулен у merged сущности
48
Пример. Merge detached сущностей
49
Пример. Merge detached сущностей
50
Работа с detached сущностями
 Пример. Проблема доступа к lazy данным detached сущности
(example_05-09)
51
Решение проблемы доступа к lazy атрибутам
detached сущности
 Планирование detachment
 Инициирование lazy загрузки (example_05-10)
 Использование eager загрузки
 Использование load tuners
 Избегание detachment
 Либо не работаем с detached сущностями из клиента
(jsp). Пока сущность managed, копируем все
необходимые данные в DTO объекты
 Либо сохраняем PC открытым все время, пока нужен
доступ к сущности (example_05-11), (example_05-12)
52
Стратегии слияния
 Использование статического сервиса. Service
(example_05-13)
 Использование сервиса, накапливающего данные.
Edit Session
(example_05-14)
53
Download