53
Entity Manager 1

Entity Manager

  • Upload
    tiger

  • View
    66

  • Download
    1

Embed Size (px)

DESCRIPTION

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 Управление транзакциями - PowerPoint PPT Presentation

Citation preview

Page 1: Entity Manager

Entity Manager

1

Page 2: Entity Manager

ОбзорОбзор

Архитектура 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

Page 3: Entity Manager

ОбзорОбзор

Операции Entity Manager Сохранение сущности Поиск сущности Удаление сущности

Каскадные операции Синхронизация с БД Detached сущности Merging Работа с detached сущностями Решение проблемы доступа к lazy атрибутам

detached сущности Стратегии слияния

Page 4: Entity Manager

Архитектура Архитектура Java Persistence APIJava Persistence API

4

Page 5: Entity Manager

Entity manager Entity manager и и Persistence ContextPersistence Context

Entity Manager – API для создания, чтения, записи и удаления сущностей из БД

API инкапсулирован в интерфейсе EntityManager

Managed сущность – это сущность, которую создал или получил Entity Manager

Набор сущностей, managed данным Entity Manager’ом в данное время называется persistence context этого Entity Manager

Только одна сущность данного типа с одинаковым идентификатором может содержаться в persistence context

5

Page 6: Entity Manager

Persistence Provider Persistence Provider ии Entity Manager Factory Entity Manager Factory

Persistence Provider определяет конкретную имплементацию интерфейса Entity Manager Отвечает за все обязанности Entity Manager:

генерацию SQL, обработку JPQL и т.д.

Entity Manager’ы создаются и конфигурируются фабрикой EntityManagerFactory

XML конфигурация данной EntityManagerFactory называется persistence unit

6

Page 7: Entity Manager

Persistence Provider Persistence Provider ии Entity Manager Factory 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

Page 8: Entity Manager

Persistence Provider Persistence Provider ии Entity Manager Factory 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

Page 9: Entity Manager

Типы Типы Entity ManagerEntity 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

Page 10: Entity Manager

Container-Managed Entity ManagerContainer-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

Page 11: Entity Manager

Transaction-Scoped Entity ManagerTransaction-Scoped Entity Manager

Когда над EM совершается некоторая операция (find, add, etc), EM проверяет, ассоциирован ли PC с данной JPA транзакцией

Если PC ассоциирован с JTA, EM использует этот PC

Если нет – EM создает пустой PC, ассоциирует его с текущей JPA транзакцией и использует

Когда транзакция завершается (commit), в БД изменяются все сущности, отслеженные EM в данном PC

После завершения транзакции (commit) PC разрушается

11

Page 12: Entity Manager

Extended Entity ManagerExtended Entity Manager

Может использоваться только для stateful beans

Detached сущность – это сущность, которая была managed некоторым EM, но была удалена из PC после его закрытия

Определяется с помощью: @PersistenceContext(unitName="EmployeeServic

e", type=PersistenceContextType.EXTENDED)

PC создается в момент создания stateful бина, удаляется в момент его удаления

12

Page 13: Entity Manager

Extended Entity ManagerExtended Entity Manager

В каждый момент завершения транзакции, все изменения с предыдущей транзакции, проведенными над сущностями PC, отслеженные EM уходят в базу.

Разница с TSEM в том, что после завершения транзакции PC не разрушается

Extended EM экономит roundtrip в БД, хорош для сервисов, которым необходима поддержка состояния

Минус в том, что stateful бины не сильно распространены

13

Page 14: Entity Manager

Application-Managed Entity ManagerApplication-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

Page 15: Entity Manager

Управление транзакциямиУправление транзакциями

Транзакция определяет когда новая, измененная или удаленная сущность будет синхронизирована с БД

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" transaction-type="RESOURCE_LOCAL"> 15

Page 16: Entity Manager

Управление Управление JPA JPA транзакциями. Определениятранзакциями. Определения

Синхронизация транзакции (transaction synchronization) – принцип, согласно которому PC связывается с транзакцией

Ассоциация транзакции (transaction association) – акт (процесс) связывания PC с транзакцией

Продление транзакции (transaction propagation) – процесс начала совместного использования (sharing) PC несколькими EM в пределах одной транзакции

16

Page 17: Entity Manager

Transaction-Scoped Persistence ContextTransaction-Scoped Persistence Context

PC продляется так же, как продляется JPA транзакция

После вызова метода, TSEM проверяет, есть ли продленный PC

Если нет, то создает его EM создает PC lazily, только если вызвана

операция на EM Таким образом, различные части приложения

(разные бины) могут использовать один и тот же PC, если они работают в одной транзакции, несмотря на то, что используют разные экземпляры EM

Пример. PC Propagation (example_05-03)17

Page 18: Entity Manager

Extended Persistence ContextExtended Persistence Context

Extended PC (PC1) создается в момент создания stateful бина SFUL1

Непосредственно (eager) в момент вызова stateful бина (или части метода бина), работающего в транзакции T1, PC1 ассоциируется с T1 Даже если с T1 уже был ассоциирован

контекст PC0 Весь последующий код, работающий в этой

же транзакции T1 будет использовать PC1

Весь PC1 будет доступен в транзакции T1, которая может его произвольно модифицировать

Пример. Extended PC (example_05-04)18

Page 19: Entity Manager

Коллизия контекстовКоллизия контекстов

Предположим, что SFUL1 был вызван из stateless бина SLESS1, который работал в транзакции T1 и имел контекст PC0

В момент вызова SFUL1 произойдет ассоциация (eager) PC1 с T1

Но PC0 уже продлен (propagated) с транзакцией T1 Произойдет коллизия контекстов

Может существовать только один активный PC в данной транзакции

Провайдер выбросит исключение Хорошо, когда stateful бин – первый в цепочке

вызовов, все последующие вызовы используют transaction scoped PC

19

Page 20: Entity Manager

Как бороться с коллизией контекстовКак бороться с коллизией контекстов

На stateful бине, определяющем extended PC: Использовать транзакционный атрибут

REQUIRES_NEW Постоянное создание новых транзакций может

отрицательно сказаться на производительности системы

Использование разных транзакций может оказаться логически неверным

Использовать транзакционный атрибут NOT_SUPPORTED Может использоваться только если логика

метода не пересекается с вызывающей логикой и не требует транзакции

Пример. Избегание коллизий (example_05-05)

20

Page 21: Entity Manager

Наследование Наследование persistence context’persistence context’овов

Если stateful бин (SB1) с extended PC (PC1) создает другой stateful бин (SB2) с extended PC, то коллизии не произойдет

Вместо этого дочерний бин SB2 будет создан с контекстом PC1

Контекст унаследуется Пример. Наследование контекстов (example_05-06)

21

Page 22: Entity Manager

Application-Managed Persistence ContextsApplication-Managed Persistence Contexts

Жизненный цикл application managed PC совпадает с жизненным циклом application managed EM

AM EM создается запросом фабрики и получением ссылки на EM из фабрики

Приложение ассоциирует AM PC с JTA транзакцией одним из двух способов: EM создается в транзакции Вызовом em.joinTransaction()

22

Page 23: Entity Manager

Application-Managed Persistence ContextsApplication-Managed Persistence Contexts

AM EM не продляют (propagate) свой PC. Следствия: Поэтому не может быть коллизий контекстов Для того, чтобы share контекст с другими

компонентами, необходимо передавать EM С данной транзакцией можно ассоциировать

произвольное количество application managed PC

Если PC синхронизирован с транзакцией, то изменения будут записаны в БД, даже если соответствующий EM будет закрыт

Пример. Наследование контекстов (example_05-07)

23

Page 24: Entity Manager

Resource-Local Resource-Local транзакциитранзакции

Resource-Local транзакции полностью управляются приложением. Нет вмешательства Java EE сервера

RL транзакция получается из application-managed EM вызовом em.getTransaction()

EntityTransaction имитирует JTA UserTransaction

24

Page 25: Entity Manager

Resource-Local Resource-Local транзакциитранзакции

Операции EntityTransaction определены через транзакционные механизмы JDBC. Нет глобального (XA) транзакционного поведения

RL транзакция не зависит от JTA транзакции и может commit или rollback без какого-либо влияния на JTA RL транзакция может использоваться для

логирования

Пример. Наследование контекстов (example_05-08)

25

Page 26: Entity Manager

Rollback Rollback транзакции и состояние сущноститранзакции и состояние сущности

Модель памяти Java не транзакционна

Когда транзакция завершается (commit), PC смотрит на все свои объекты, которые удалены, изменены или созданы и генерирует SQL для обновления БД

Выполнение этого SQL может прерваться (rollback). Произойдет 2 вещи: Изменения в БД откатятся PC очистится, все managed сущности станут

detached

Произойдет рассинхранизация БД и detached объектов в памяти Рассмотреть возможность сделать попытку второго

commit и выполнить слияние (merge) сущностей26

Page 27: Entity Manager

Какой Какой Entity manager Entity manager использоватьиспользовать

Для большинства Java EE приложений подойдет Container-Managed Transaction-Scoped EM Таковой была имплементация многих

коммерческих ORM фреймворков (TopLink) Наиболее понятна семантика работы

Идея Extended PC была введена впервые в JPA Есть performance плюсы Есть ограничения (коллизии)

27

Page 28: Entity Manager

Какой Какой Entity manager Entity manager использоватьиспользовать

Использование Application-Managed PC в Java EE средах не очень хорошая идея Нет context propagation

Application-Managed PC Может отлично использоваться в Java SE средах, а так же в custom фреймворках

Смешивать разные типы EM в архитектуре одного приложения определенно плохая идея

28

Page 29: Entity Manager

Операции Операции Entity Manager. Entity Manager. Сохранение сущностиСохранение сущности

Метод em.persist(e) принимает новую сущность и делает ее managed

Если е уже managed, ничего не происходит При вызове persist() данные не сохраняются в БД.

Будут сохранены при синхронизации PC с БД (commit, flush) При вызове persist() вне транзакции в

transaction-scoped EM, будет возбужден TransactionRequiredException

Однако, EM может теперь отслеживать все изменения над Java экземпляром e

29

Page 30: Entity Manager

Операции Операции Entity Manager. Entity Manager. Сохранение сущностиСохранение сущности

EntityExistException будет возбужден: При вызове persist(), если EM обнаружит, что

сущность с тем же идентификатором уже managed

При commit в БД, если на уровне SQL обнаружится, что сущность с тем же идентификатором уже существует в БД

Пример:

30

Page 31: Entity Manager

Операции Операции Entity Manager. Entity Manager. Поиск сущностиПоиск сущности

em.find(key) выбирает сущность из БД или из PC

Возвращенная сущность будет managed За исключением вызова find() вне транзакции в

transaction-scoped EM. В этом случае она будет detached

31

Page 32: Entity Manager

Операции Операции Entity Manager. Entity Manager. Поиск сущностиПоиск сущности

Когда target сущность в отношении one-to-one или many-to-one существует в БД и ее ключ известен, нет нужды делать SQL для выборки этой сущности

getReference(key) возвращает прокси объект, в котором определен только идентификатор сущности

EntityNotFoundException будет возбужден при выхове любого метода, кроме getID()

Проксируемая сущность должна существовать в таблице

32

Page 33: Entity Manager

Операции Операции Entity Manager. Entity Manager. Удаление сущностиУдаление сущности

em.remove(e) используется для удаления сущности e

Данные реально удалятся из БД, при commit транзакции

Обслуживание отношений выполняет приложение, не JPA!

33

Page 34: Entity Manager

Операции Операции Entity Manager. Entity Manager. Удаление сущностиУдаление сущности

Только для managed сущности может быть вызван em.remove()

Вызов em.remove() вне транзакции

в transaction-scoped EM приведет к TransactionRequiredException

В остальных типах EM ничего не произойдет: Никакой exception не возбудится Сущность не удалится из БД

34

Page 35: Entity Manager

Каскадные операцииКаскадные операции

По умолчанию операция EM применяется только к сущности, передаваемой в качестве аргумента. Не продолжается (cascade) на другие сущности в отношении

Это не ограничение спецификации. Приложение должно иметь контроль над тем, что удаляется, что создается и т.д.

В примере ниже разумно продолжать (cascade) операцию persist автоматически при сохранении адреса

35

Page 36: Entity Manager

Cascade PersistCascade Persist

Все каскадные установки однонаправленные Операция persist для managed сущности не имеет

никакого эффекта для этой сущности, но для ее атрибутов выполнятся cascade persist операции

36

Page 37: Entity Manager

Cascade RemoveCascade Remove

Упоминалось о том, что это обязанность приложения занулять ссылки. Ставить везде CascadeType.REMOVE не разумно

Только в случае one-to-one и one-to-many можно относительно безопасно использовать каскадное удаление

При условии, что target сущности можно безопасно удалить

37

Page 38: Entity Manager

Синхронизация с БДСинхронизация с БД

PC сбрасывается (flush) каждый раз, когда генерируется и исполняется SQL

Flush происходит в двух случаях: Транзакция завершается (commit) Делается вызов em.flush()

Провайдер может сделать flush в любой момент, например: JPQL зависит от данных PC

Flush происходит для сущностей: Новых Измененных Удаленных

38

Page 39: Entity Manager

Синхронизация с БД. Синхронизация с БД. PersistPersist

Flush новой сущности логически эквивалентен вызову persist второй раз на этой сущности

39

Page 40: Entity Manager

Синхронизация с БД. Синхронизация с БД. PersistPersist

В общем виде, исключение будет возбуждено, если managed сущность имеет ссылки на не-managed сущности: Detached сущность Новая сущность

Исключение из этого правила: Detached сущность является target сущностью

one-to-one или many-to-one отношения Новая сущность имеет каскадный атрибут

CascadeType.PERSIST

В идеале, при persist весь граф объектов должен быть managed

40

Page 41: Entity Manager

Синхронизация с БД. Синхронизация с БД. RemoveRemove

Удаляется сущность: Так как flush в БД может произойти в любое

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

которые ссылаются на удаляемую сущность

Непонимание этого факта может приводить к мистически, плавающим ошибкам

41

Page 42: Entity Manager

Detached Detached сущностисущности

Существует несколько причин, по которым сущность может стать detached: транзакция в transaction-scoped EM commit, PC

разрушается application-managed PC закрывается stateful бин с extended PC удаляется (метод

@Remove) вызван clear() метод у EM когда происходит rollback, все сущности в PC

становятся detached когда сущность сериализуется, она

отсоединяется от PC42

Page 43: Entity Manager

Detached Detached и и Managed Managed сущностисущности

У managed сущности мы можем вызвать любой lazy атрибут. JPA сделает SQL вызов и выберет нужную информацию из БД

Lazy-loaded атрибуты detached сущности, к которым не было вызова в момент, когда сущность еще была managed представляют проблему. Спецификация JPA не определяет поведение провайдера в этом случае. Варианты: Провайдер все же постарается подгрузить

сущность Сущность останется не

проинициализированной Выкинет исключение

43

Page 44: Entity Manager

Пример. Пример. Lazy fetch Detached Lazy fetch Detached сущностисущности

44

Page 45: Entity Manager

Detachment Detachment и и mergingmerging

Никакие программные изменения над detached сущностью не будут commit в БД, т.к. EM не отслеживает эту сущность

Слияние (merge) это процесс обратной интеграции detached сущности в EM

Возможно offline изменение сущности (возможно в другой JVM) с последующим слиянием этой сущности в EM и commit в БД

45

Page 46: Entity Manager

Merge detached Merge detached сущностейсущностей

Метод E1=em.merge(E) делает merge detached сущности E обратно в PC

Сущность E не станет managed, ею будет E1!!!

46

Page 47: Entity Manager

Merge detached Merge detached сущностейсущностей

Если X является detached сущностью, состояние X скопируется в уже существующую managed сущность X' с тем же идентификатором, либо создается новая managed сущность X'

Если X это новая сущность, то создается новая managed сущность X' и состояние X копируется в X'

Если X это удаленная сущность, исключение IllegalArgumentException будет возбуждено (либо транзакция откатиться)

47

Page 48: Entity Manager

Merge detached 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

Page 49: Entity Manager

Пример. Пример. Merge detached Merge detached сущностейсущностей

49

Page 50: Entity Manager

Пример. Пример. Merge detached Merge detached сущностейсущностей

50

Page 51: Entity Manager

Работа с Работа с detached detached сущностямисущностями

Пример. Проблема доступа к lazy данным detached сущности (example_05-09)

51

Page 52: Entity Manager

Решение проблемыРешение проблемы доступа к доступа к lazy lazy атрибутам атрибутам detached detached сущностисущности

Планирование detachment Инициирование lazy загрузки (example_05-10)

Использование eager загрузки Использование load tuners

Избегание detachment Либо не работаем с detached сущностями из

клиента (jsp). Пока сущность managed, копируем все необходимые данные в DTO объекты

Либо сохраняем PC открытым все время, пока нужен доступ к сущности (example_05-11), (example_05-12)

52

Page 53: Entity Manager

Стратегии слиянияСтратегии слияния

Использование статического сервиса. Service (example_05-13)

Использование сервиса, накапливающего данные. Edit Session (example_05-14)

53