Рассматриваемые темы Java Persistence API Сущности (Entities) Транзакции в JPA Иерархия классов и JPA Связи в JPA EJB-QL Обработчики (Listeners) 2-1 Java Persistence API Место JPA 2-2 Java Persistence API Цели JPA Автоматическое отслеживание статуса сущности и его сохранение Простота конфигурации Унифицированный интерфейс Свобода от закрытых решений 2-3 Java Persistence API Что такое JPA? EJB 3 Persistence Слой объектно-реляционного преобразования JSR-220 Направлен на использование реляционных БД Простой API Мощный язык запросов 2-4 Java Persistence API Что такое Модуль JPA Persistence? Имеет имя Имя может быть пустым, если в приложении только один модуль Ассоциируется с: Набором классов сущностей БД для хранения информации Единая конфигурация Единый набор метаданных 2-5 Java Persistence API Что такое “управляемые сущности”? JPA отслеживает управляемые (managed) сущности Их изменения фиксируются в БД при завершении транзакции JPA загружает поля и связи управляемых объектов по запросу приложения Отсоединенные и вновь созданные сущности не являются managed 2-6 Java Persistence API Что такое PersistenceContext? Набор управляемых объектов в одном Persistence-модуле Каждый EntityManager связан c одним PersistenceContext'ом PersistenceContext может быть связан с несколькими EntityManager'ами 2-7 Java Persistence API У PersistenceContext есть диапазон PersistenceContextType.TRANSACTIONAL PersistenceContextType.EXTENDED По умолчанию в J2SE В Java EE 5 Для компонентов с управляемыми транзакциями по умолчанию — TRANSACTIONAL Для остальных по умолчанию - EXTENDED 2-8 Java Persistence API PersistenceContext с TRANSACTIONAL диапазоном Managed сущности при фиксации транзакции отсоединяются Загруженные сущности Становятся managed только если транзакция активна Сущности не могут быть изменены вне транзакции Иначе возникает TransactionRequiredException 2-9 Java Persistence API PersistenceContext с EXTENDED диапазоном Managed сущности при фиксации транзакции остаются managed Загруженные сущности managed независимо от транзакций Сущности могут быть изменены вне транзакции Изменения сохраняются если позже транзакция начата и зафиксирована 2-10 Java Persistence API EntityManager JPA 2-11 Java Persistence API Как EntityManager отслеживает изменения статуса? Расширение байт-кода Разработка POJO-сущности Определение хранимых полей с помощью метаданных Компиляция Расширение байт-кода 2-12 Java Persistence API EntityManager в EJB3 @Stateless public class ServiceBean implements Service { @PersistenceContext EntityManager em; ... } ServiceBean.java Параметры аннотации: unitName — имя JPA модуля type: PersistenceContextType.TRANSACTIONA L 2-13 PersistenceContextType.EXTENDED Java Persistence API Методы жизненного цикла в интерфейсе EntityManager boolean isOpen() IllegalStateException если EM получен с помощью Injection IllegalStateException если транзакция активна После закрытия все методы вызывают IllegalStateException void close() 2-14 Java Persistence API Интерфейс EntityManager void persist(Object entity) Делает вновь созданную сущность управляемой Данные сохраняются при фиксации транзакции void remove(Object entity) Помечает сущность к удалению Удаление происходит при фиксации транзакции 2-15 Java Persistence API Интерфейс EntityManager void refresh(Object entity) Обновляет данные в сущности Перезаписывает все изменения T find(Class<T> entityClass, Object key) Может вернуть null Предпочтительнее, чем getReference T getReference(Class<T> entityClass, Object key) Не возвращает null 2-16 Java Persistence API Утилитный класс Persistence в JPA Содержит два метода для получения EntityManagerFactory puName — имя Persistence модуля Может быть пустым Опция Map позволяет задавать специфичные параметры 2-17 Java Persistence API Интерфейс EntityManagerFactory Содержит два метода для получения EntityManager createEntityManager() createEntityManager(Map map) Содержит два метода жизненного цикла boolean isOpen() void close() 2-18 Java Persistence API EntityManagerFactory 2-19 Java Persistence API Типовой жизненный цикл приложения, использующего БД Получить запрос пользователя Решить, стоит ли открывать контекст транзакции Найти хранимые объекты Изменить хранимые объекты Принять решение о фиксации/ отмене/продолжении транзакции Повтор 2-20 Java Persistence API Дизайн Model в архитектуре MVC как сервиса для приложения Модель должна знать, как: Найти хранимые объекты Изменить хранимые объекты Обработать транзакции Следить за целостностью Модель не должна знать об остальном приложении Приложение обращается к модели 2-21 Java Persistence API Архитектура MVC-приложения 2-22 Java Persistence API Архитектура MVC-приложения Сервис в модели предоставляет: Поиск Обработку сохранения Может быть несколько сервисов Решения об использовании объектов модели вне модели detached или управляемые сущности Решения о контроле транзакций 2-23 Рассматриваемые темы Java Persistence API Сущности (Entities) Транзакции в JPA Иерархия классов и JPA Связи в JPA EJB-QL Обработчики (Listeners) 2-24 Сущности (Entities) Требования к хранимым классам Должны быть top-level классами Не могут быть final Не могут иметь final поля или методы Должны иметь public или protected конструктор без аргументов 2-25 Сущности (Entities) Требования к хранимым классам Должны иметь объявленный первичный ключ Могут быть абстрактными и конкретными Должны идентифицироваться в метаданных мапинга Хранимые поля должны быть поддерживаемых типов 2-26 Сущности (Entities) Что такое метаданные мапинга? Информация, необходимая JPAимплементации для обеспечения взаимодействия объектной модели и БД Имя таблицы в БД Первичные ключи Каскадирование для связей Стратегия и поля версий И т.д. 2-27 Сущности (Entities) Определение метаданных мапинга Аннотации JPA Наш курс использует только аннотации XML-файлы (ORM-файлы) Настройки, указаннае в файлах, более приоритетны, чем соответствующие аннотации 2-28 Сущности (Entities) Классы сущностей Используйте аннотацию Entity Могут наследоваться от Mapped Superclass Других классов сущностей Нехранимых классов Поля нехранимых классов никогда не сохраняются 2-29 Сущности (Entities) Два типа доступа в JPA Доступ к свойствам С помощью JavaBean-методов Доступ к полям Один тип доступа применяется ко всей иерархии сущностей Определяется Положением первой аннотации Значением тэга <access> в метаданных 2-30 Сущности (Entities) Требования для доступа к свойствам Свойства должны иметь методы get и set Методы свойств должны быть public или protected Аннотируется только метод get JPA-имплементация будет использовать эти методы Бизнес-логика в аксессорах может привести к побочным эффектам 2-31 Сущности (Entities) Требования для доступа к полям Поля должны быть public, package или protected Аннотируются поля JPA-имплементация обеспечивает доступ к этим полям Рекомендуется использовать доступ к полям 2-32 Сущности (Entities) Идентификатор (ключ) сущности Однозначно идентифицирует состояние сущности в БД Может состоять из одного или нескольких полей Ссылки на другие сущности не могут быть ключами Должен быть определен для старшего класса иерархии 2-33 Сущности (Entities) Аннотации простого ключа Аннотация @Id По умолчанию ключ должен определяться приложением @GeneratedValue Параметры: strategy — GenerationType AUTO — по умолчанию TABLE, SEQUENCE, IDENTITY generator 2-34 Сущности (Entities) Составные ключи Использует определенный в приложении класс ключа public-класс верхнего уровня или public static вложенный класс Реализует Serializable public конструктор по умолчанию Методы hashCode и equals используют ключевые поля 2-35 Сущности (Entities) Аннотации составных ключей Аннотирование класса ключа и его полей Аннотирование поля встроенного ключа 2-36 Сущности (Entities) Хранимые поля Значения хранимых полей сохраняются в БД Два типа хранимых полей: Простые (поля-значения) Отношения (связи) transient и @Transient поля не могут быть хранимыми Остальные поля хранимы по умолчанию 2-37 Сущности (Entities) Типы простых полей Примитивные типы и их обертки java.lang.String java.math.BigInteger/BigDecimal java.util.Date/Calendar java.sql.Date/Time/Timestamp Массивы Byte, Byte, char, Char Перечисления Любой Serializable класс 2-38 Сущности (Entities) Аннотации простых полей Аннотация @Basic Опциональна, но рекомендуется для определения типа доступа Два параметра: fetch FetchType.EAGER (по умолчанию) FetchType.LAZY optional true (по умолчанию для непримитивов) false (по умолчанию для примитивов) 2-39 Сущности (Entities) Аннотация @Temporal Дополняет аннотацию @Basic Применяется к полям типа java.util.Date/Calendar Возможные значения: TemporalType.DATE TemporalType.TIME TemporalType.TIMESTAMP 2-40 Сущности (Entities) Аннотация @Enumeration Дополняет аннотацию @Basic Применяется к полям-перечислениям Возможные значения: EnumType.ORDINAL EnumType.STRING 2-41 Сущности (Entities) Что такое отсоединенные сущности? Экземпляры хранимых классов Отсоединены от EntityManagerа После отсоединения, EM не загружает поля «по запросу» Изменения непосредственно не отображаются в БД Могут быть изменены вне активной транзакции 2-42 Сущности (Entities) Создание отсоединенных сущностей Отсоединение происходит, когда: Закрывается EM У EM вызывается метод clear() Сущность проходит через сериализацию Транзакция откатывается При откате активной транзакции вызывается метод clear() 2-43 Сущности (Entities) Создание отсоединенных сущностей В транзакционном контексте отсоединение происходит: При выполнении запроса вне транзакции После фиксации транзакции Если объект изменен, предполагается, что изменения будут зафиксированы Поле версии соответствует ожидаемому после фиксации 2-44 Сущности (Entities) Проверка на отсоединенность Метод интерфейса EntityManager contains Определяет, является ли сущность управляемой 2-45 Сущности (Entities) Загрузка полей при отсоединении Загруженными остаются поля, загруженные у управляемой сущности Загруженные связи сохраняются Создается граф отсоединенных объектов Загружаются: Поля с ранней загрузкой (по умолчанию) и поля с поздней загрузкой, уже запрошенные приложением и загруженные Поля, загруженные при join 2-46 Сущности (Entities) Объединение (merging) Отсоединенные сущности могут быть объединены с текущим контекстом EM Копирует измененные поля в управляемую сущность Если сущность новая, то создается новый управляемый экземпляр 2-47 Сущности (Entities) Объединение (merging) Связи обрабатываются рекурсивно, если Выставлен атрибут cascade=CascadeType.MERGE И связь загружена в отсоединенный объект Изменения в результате объединения сохраняются при фиксации транзакции 2-48 Рассматриваемые темы Java Persistence API Сущности (Entities) Транзакции в JPA Иерархия классов и JPA Связи в JPA EJB-QL Обработчики (Listeners) 2-49 Транзакции в JPA ACID - свойства транзакции БД может выполнять несколько транзакций одновременно Каждая транзакция может включать несколько шагов Свойства транзакции: Atomicity — атомарность Consistency — надежность Isolation — изоляция Durability — долговечность 2-50 Транзакции в JPA Транзакционные характеристики Целостность обновления Изменения не могут быть зафиксированы, если изменяемые данные устарели Надежность чтения Все данные, считанные в течение транзакции, не устарели к моменту фиксации изменений 2-51 Транзакции в JPA Целостность обновления Пессимистичные блокировки Реализация уровня изоляции повторных чтений Оптимистичные проверки модифицируемых объектов Изоляция на основе упорядочивания 2-52 Транзакции в JPA Надежность чтения Пессимистичные блокировки Оптимистичные проверки читаемых объектов Реализация изоляции на основе упорядочивания 2-53 Транзакции в JPA Пессимистичные блокировки Клиент получает эксклюзивное право на чтение записи Уменьшает максимально допустимое количество обращений Deadlock возможен, его избежание — забота разработчика Не определены в JPA 2-54 Транзакции в JPA Оптимистичные проверки Имплицитно выполняются JPA на изменяемых объектах Необходимо поле версии (@Version) При изменении проверяется версия Несоответствие версии ведет к откату транзакции Из-за отсутствия блокировок возможно максимальное количество обращений 2-55 Транзакции в JPA Аннотация @Version int, short, long, Integer, Long, Short, java.sql.Timestamp Поле не должно изменяться приложением Без поля версии, пересекающиеся изменения не распознаются 2-56 Транзакции в JPA Проверки в приложении Некоторые приложения могут декомпозировать сущности Web-приложения посылают клиенту атрибуты Приложение может производить самостоятельный контроль версий и посылать клиенту исключения 2-57 Транзакции в JPA Явные блокировки в JPA EntityManager предоставляет метод lock public void lock(Object entity, LockModeType mode) Сущность должна быть управляемой Транзакция активна должна быть 2-58 Транзакции в JPA Блокировки на чтение Метод lock с LockTypeMode.READ Две транзакции, запрашивающие блокировку на чтение на одну и ту же сущность, успешны, если: Ни одна не изменяет сущность Или реализация заставляет транзакцию сериализоваться Для успешных транзакций чтение при использовании блокировки на чтение целостно 2-59 Транзакции в JPA Блокировки на запись Метод lock с LockTypeMode.WRITE Приводит к запросу блокировки в БД или проверке версии при фиксации изменений Требует изменения версии сущности Две транзакции, запрашивающие блокировку на чтение на одну и ту же сущность, успешны, если: Реализация требует сериализации транзакции 2-60 Транзакции в JPA Исключения OptimisticLockException Возникает в методах merge или flush Помечает транзакцию к откату Может возникнуть в методе commit RollbackException Возникает при неудаче метода commit, если происходит откат транзакции 2-61 Практика Упражнение Разработка сохраняемых простых сущностей с использованием транзакционных механизмов. 2-62 Рассматриваемые темы Java Persistence API Сущности (Entities) Транзакции в JPA Иерархия классов и JPA Связи в JPA EJB-QL Обработчики (Listeners) 2-63 Иерархия классов и JPA Классы в иерархии сущностей Классы, не являющиеся сущностями, могут присутствовать в иерархии Хорошая практика делать их абстрактными Классы сущностей могут быть абстрактными и конкретными 2-64 Иерархия классов и JPA Стратегии маппинга наследования Mapped Superclass Единая таблица Объединение таблиц Таблица на класс 2-65 Иерархия классов и JPA Mapped Superclass Аннотация класса без параметров MappedSuperclass не отображается на отдельную таблицу Не может участвовать в запросах, в отношениях Может быть только на самом верху иерархии 2-66 Иерархия классов и JPA Аннотация наследования Определяет одну из трех стратегий: Единая таблица (SINGLE_TABLE) Объединение таблиц (JOINED) Таблица на класс (TABLE_PER_CLASS) Используется на старшем классе в иерархии (не MappedSuperclass) 2-67 Иерархия классов и JPA Стратегия единой таблицы Все классы хранятся в одной таблице Быстрая, простая модель Хорошо протестирована Использует столбец- дискриминатор 2-68 Иерархия классов и JPA Использование единой таблицы Отличный выбор, когда Данные сосредоточены в верхних классах иерархии Поведение — в нижних Не рекомендуется, если данные распределены в большой иерархии Таблица с множеством столбцов Большинство столбцов nullable Невозможно применение простых ограничений (constraints) 2-69 Иерархия классов и JPA Стратегия объединения таблиц Каждый класс хранится в своей таблице Абстрактные классы тоже отображаются Использует столбец- дискриминатор 2-70 Иерархия классов и JPA Особенности объединения таблиц Преимущества Наиболее нормализованные таблицы Нет проблем с ограничениями (constraints) на столбцах Модель данных легко расширяема Недостатки Чтение приводит к объединению или нескольким запросам Вставка и обновление затрагивают несколько таблиц 2-71 Иерархия классов и JPA Использование объединения таблиц Отличный выбор, когда Иерархия не слишком глубока Необходимые объединения при чтении не приводят к потере производительности Не много обновлений данных Данные распределены по иерархии Не рекомендуется, если Множество классов в иерархии добавляет лишь поведенческие особенности 2-72 Иерархия классов и JPA Аннотация @DiscriminatorColumn Определяет столбец-дискриминатор При хранении информации о нескольких классах в одной таблице, необходимо средство их дискриминации Реализация создает столбец при необходимости 2-73 Иерархия классов и JPA Стратегия таблицы на класс Каждый конкретный класс — в своей таблице Абстрактные классы отображаются на таблицы наследников Столбец-дискриминатор не используется 2-74 Иерархия классов и JPA Преимущества таблицы на класс Исправляет недостатки двух предыдущих стратегий Разделяет данные в несколько таблиц Позволяет избежать объединений при операциях с известным типом Наиболее быстрый вариант при операциях с определенным типом Затрагивается одна таблица Меньше строк и столбцов для получения 2-75 Иерархия классов и JPA Недостатки таблицы на класс Значительные ограничения на полиморфные отношения Например: Получение Set<Person> em.find(Person.class, id) Приводят к многочисленным запросам или одному запросу с множеством объединений 2-76 Рассматриваемые темы Java Persistence API Сущности (Entities) Транзакции в JPA Иерархия классов и JPA Связи в JPA EJB-QL Обработчики (Listeners) 2-77 Связи в JPA Свойства связей Количество элементов Один-к-одному Один-ко-многим Много-ко-многим Зависимость Ассоциация Композиция Направление Однонаправленные Двунаправленные 2-78 Связи в JPA Двунаправленные связи В SQL все связи — двунаправленные В Java все связи — однонаправленные Двунаправленные связи в Java моделируются двумя однонаправленными Две ссылки в памяти моделируют одно значение в реляционной БД Приложение должно управлять двунаправленными связями в Java 2-79 Связи в JPA Каскадирование в JPA Свойство Cascade Определяет действия менеджера сущностей по отношению к связанным сущностям CascadeType enum PERSIST REMOVE, REFRESH, MERGE, ALL Каскадирование в JPA по умолчанию отключено 2-80 Связи в JPA Выборка (fetch) в JPA Fetch определяет при выборке сущности действия со связанными сущностями FetchType enum EAGER Связанная сущность загружается вместе со связывающей По умолчанию для «к-одному» связей 2-81 Связи в JPA Выборка (fetch) в JPA LAZY Связанная сущность загружается при первом использовании в приложении По умолчанию для «ко-многим» связей «Совет» JPA-механизму, который может по своему усмотрению использовать «раннюю» выборку 2-82 Связи в JPA Поддерживаемые типы связей в JPA Интерфейсы из java.util: Collection Set List Map Коллекции должны быть коллекциями сущностей Map'ы должны иметь примитивные ключи и значения-сущности 2-83 Связи в JPA Сортировка списков в JPA Списки не сортируются имплицитно Для указания сортировки используется аннотация @OrderBy JPA использует сортировку только при выборке 2-84 Связи в JPA Четыре стандартных аннотации связей 2-85 Связи в JPA Атрибуты аннотаций связей Атрибут fetch Значение по умолчанию зависит от типа отношений Атрибут cascade По умолчанию — отсутствие каскадирования 2-86 Связи в JPA Один-к-одному Все «к-одному» отношения имеют атрибут optional По умолчанию — true Если связь двунаправленная, одна из сторон — владелец Вторая сторона использует атрибут mappedBy 2-87 Связи в JPA Один-к-одному Все «к-одному» отношения имеют значение атрибута fetch по умолчанию EAGER Переопределение: Столбец вторичного ключа имеет ограничение на уникальность 2-88 Связи в JPA Много-к-одному Всегда владелец какой-либо двунаправленной связи Значение атрибута fetch по умолчанию — EAGER Вторичный ключ не имеет ограничения на уникальность 2-89 Связи в JPA Один-ко-многим Значение атрибута fetch по умолчанию для всех «ко-многим» связей — LAZY В случае двунаправленных связей используется атрибут mappedBy 2-90 Связи в JPA Много-ко-многим Значение атрибута fetch по умолчанию — LAZY Всегда моделируются соединением таблиц В случае двунаправленной связи используется mappedBy 2-91 Связи в JPA Много-ко-многим Значение атрибута fetch по умолчанию — LAZY Всегда моделируются соединением таблиц В случае двунаправленной связи используется mappedBy 2-92 Связи в JPA Map в JPA Один-ко-многим или много-комногим Ключ всегда является одним из полей сущности-значения 2-93 Рассматриваемые темы Java Persistence API Сущности (Entities) Транзакции в JPA Иерархия классов и JPA Связи в JPA EJB-QL Обработчики (Listeners) 2-94 EJB-QL Запросы Имя сущности — простое имя класса Ключевые слова не чувствительны к регистру, имена сущностей, полей и параметры - чувствительны 2-95 EJB-QL Создание запросов Запросы создаются фабричными методами EntityManager'а Фильтры для именованных запросов определяются в метаданных 2-96 EJB-QL Синтаксис оператора select Общий синтаксис: select [distinct] [<что?>] from <откуда?> [where <условие>] [ group by <группировка>] [ having <условие>] [ order by <сортировка>] Синтаксис близок к SQL 2-97 EJB-QL Типы выборки Выборка сущностей: Выборка агрегатных значений: Выборка проекций: Выборка пользовательских классов 2-98 EJB-QL Использование Dot-нотации Примеры использования: Если при вычислении логического выражения появляется null, выражение принимает значение false 2-99 EJB-QL Использование объединений Пример использования: Необходимо использовать ключевое слово distinct Inner join (join) Left join (left outer join) 2-100 EJB-QL Условные выражения Сравнение >,<,>=,<=,=,<> like is [not] null is [not] empty <значение> in <список> <значение> in <подзапрос> <оператор> {ALL|SOME|ANY} (подзапрос) 2-101 EJB-QL Логические операторы Три стандартных оператора для комбинирования условий and or not 2-102 EJB-QL Параметры Параметры именуются в запросе с помощью: Имени: :bName, :x... Позиции: ?1, ?2... Параметры выставляются до выполнения запроса: setParameter(String name,Object val) setParameter(int pos, Object val) 2-103 EJB-QL Выборка при объединении В запросе можно указать тип «ранней» выборки с помощью fetch для «ко-многим» связей Нельзя обращаться к выбираемой сущности в запросе 2-104 EJB-QL Ограничение количества выборки Два метода класса Query: setFirstResult(int startPos) Нумерация с 0 setMaxResults(int limit) 2-105 EJB-QL Выполнение запросов Два метода для выборки: List getResultList() Object getSingleResult() EntityNotFoundException NonUniqueResultException Один метод для обновления: int executeUpdate() Возвращает количество измененных записей 2-106 EJB-QL Массовые операции Обновление Обновляет поле версии (если есть) Удаление Не требует загрузки объектов Массовые изменения не затрагивают управляемых объектов в текущем контексте любого менеджера 2-107 EJB-QL Именованные запросы Именованные запросы могут определяться в аннотациях Так же могут определяться в конфигурационном файле createNamedQuery(String name) 2-108 Практика Упражнение Разработка сохраняемых сложных сущностей с иерархиями наследования и связями. 2-109 Рассматриваемые темы Java Persistence API Сущности (Entities) Транзакции в JPA Иерархия классов и JPA Связи в JPA EJB-QL Обработчики (Listeners) 2-110 Обработчики Виды обработчиков Обработчики жизненного цикла сущности PrePersist PostPersist PreRemove PostRemove PreUpdate PostUpdate PostLoad 2-111 Обработчики Определение обработчиков Вынесение логики обработчиков в отдельный класс и использование @EntityListeners Использование аннотаций обработчиков жизненного цикла в классе сущности 2-112 Обработчики Управление обработчиками Предотвращение вызова обработчиков предка @ExcludeSuperclassListeners Предотвращение вызова обработчиков по умолчанию @ExcludeDefaultListeners 2-113 Практика Упражнение Разработка обработчиков. 2-114 Рассмотренные темы Java Persistence API Сущности (Entities) Транзакции в JPA Иерархия классов и JPA Связи в JPA EJB-QL Обработчики (Listeners) 2-115