- •Обозначения и сокращения
- •введение
- •1. Установка и настройка инструментальных средств
- •1.1. Установка и подготовка к работе операционной системы
- •1.2. Установка программного обеспечения
- •1.3. Создание таблиц в базе данных
- •2. Основы Java EE 6
- •2.1. Распределенные многоуровневые приложения
- •2.2. Контейнеры Java EE
- •2.3. Сервер GlassFish v3
- •2.4. Структура приложения
- •2.5. Конфигурирование приложений
- •2.6. Задание ссылок на ресурсы
- •4. Введение в компоненты Facelets
- •4.1. Веб-страницы
- •4.2. Разработка простого приложения Facelets
- •4.3. Использование шаблонов
- •5. Унифицированный язык записи выражений
- •6.1. Добавление компонент библиотеки HTML на страницу
- •6.2. Использование компонент для таблиц баз данных
- •6.3. Использование тегов библиотеки Core
- •7. Использование конвертеров, слушателей и проверок
- •7.1. Использование стандартных преобразователей
- •7.2. Регистрация слушателей для компонентов
- •8. Внешние объекты (JavaBeans)
- •8.1. Создание класса внешних объектов
- •8.2. Описание свойств бинов
- •8.3. Написание методов внешних бинов
- •8.4. Проверка бинами
- •9.1. Файл конфигурации ресурсов приложения
- •9.2. Упорядочение ресурсов конфигурации приложения
- •9.3. Конфигурирование состояния проекта
- •9.4. Выбор конфигурации бина
- •9.5. Регистрация сообщений об ошибках как пакет ресурса
- •9.7. Конфигурирование правил навигации (Navigation Rules)
- •9.8. Основные требования приложения JavaServer Faces
- •10. Технология Java Servlet
- •11. Введение в Java Persistence API
- •11.1. Требования к классам сущностей
- •11.3. Внедряемые классы в сущностях
- •11.4. Наследование сущностей
- •11.5. Стратегии наследования сущностей с отображением
- •11.6. Управление сущностями
- •11.7. Запросы сущностей
- •12. Примеры хранимых сущностей
- •12.1. Приложение order
- •12.2. Пример получения схемы отношений на основе таблиц БД
- •13.1. Терминология языка запросов
- •13.3. Упрощенный синтаксис языка запросов
- •13.4. Примеры запросов
- •13.5. Запросы с навигацией связанных сущностей
- •13.6. Запросы с другими условными выражениями
- •13.7. Изменение и удаление группы сущностей
- •13.8. Полный синтаксис языка запросов
- •14. Язык запросов Criteria API
- •14.3. Корни запроса
- •14.4. Использование объединения в запросе
- •14.5. Навигация путей в запросах
- •14.6. Ограничения на результаты запроса
- •14.7. Управление результатами запросов
- •14.8. Исполнение запросов
- •15. Связывание ресурсов
- •15.1. Ресурсы и служба имен JNDI
- •15.2. Объекты DataSource и пулы соединений (Connection Pools)
- •15.3. Внедрение ресурсов
- •15.4. Адаптеры ресурсов
- •15.5. Аннотации метаданных
- •16. Безопасность веб-приложений
- •16.1. Краткий обзор
- •16.2. Механизмы обеспечения безопасности
- •16.3. Безопасность сервера предприятия
- •16.4. Использование защищенного соединения SSL
- •18. Пример приложения
- •18.1. Создание проекта веб-приложения
- •18.3.Структура приложения JavaEE 6
- •18.4. Программирование вида для объектов
- •18.5. Дизайн главной страницы
- •18.6. Страница просмотра записей таблицы городов
- •18.7. Страница добавления записей о городах
- •18.8. Страница редактирования записей о городах
- •18.9. Страница удаления записей о городах
- •19. Обработка связей внешних ключей
- •19.1. Разработка класса для вида сущности
- •19.2. Доработка вида для городов
- •19.3. Разработка обзорной страницы
- •19.5. Страница для редактирования записей с внешними ключами
- •20. Дополнительные функции
- •20.1. Сортировка записей таблицы
- •20.2. Контроль за удалением связанных записей
- •20.3. Контроль ввода наименований
- •20.4. Запросы к БД на языке Java Persistence Query Language
- •20.5. Управление страницами при просмотре таблицы
- •20.6. Создание и просмотр отчетов
- •20.7. Использование шаблонов и стилей
- •20.8. Защита приложения паролем
- •Заключение
- •Библиографический список
|
Таблица 11.1 |
|
Каскадные операции для сущностей |
|
|
Операция |
Описание |
ALL |
Все каскадные операции будут применены к связанному |
|
с родительским объекту.ALL — эквивалент определению |
|
cascade={DETACH, MERGE, PERSIST, REFRESH, REMOVE} |
DETACH |
Если родительский объект отделен из контекста хранения, |
|
связанный объект также будет отделен |
MERGE |
Если родительский объект объединен в контекст хранения, |
|
то связанный объект также будет объединен |
PERSIST |
Если родительский объект храним в контексте, то связанный |
|
объект также будет хранимым |
REFRESH |
Если родительский объект обновлён в текущем контексте |
|
хранения, то связанный объект также будет обновлён |
REMOVE |
Если родительский объект удален из текущего контекста |
|
хранения, связанный объект также будет удален |
Одиночное удаление
Когда целевой объект во взаимно-однозначном отношении или отношении «один-ко-многим» удален из отношения, часто желательна операция каскадного удаления целевого объекта. Такие целевые объекты считаются сиротами (orphans).
Чтобы удалить «осиротевшие» (orphaned) объекты, можно использовать атрибут orphanRemoval. Например, если заказ имеет много пунктов и один из пунктов удален из заказа, удаленный пункт считается «сиротой». Если атрибут orphanRemoval установлен в true, то строка пункта будет удалена, когда пункт будет удален из заказа.
Атрибут orphanRemoval в @OneToMany и @oneToOne принимает логическое значение, по умолчанию — false.
Пример допустимого каскадного удаления «сиротских» записей в отношении
@OneToMany:
@OneToMany(mappedBy="customer", orphanRemoval="true") public List<Order> getOrders() { ... }
11.3. Внедряемые классы в сущностях
Внедренные (embeddable) классы используются, чтобы представлять состояние
объекта, не тождественное хранимому, в отличие от классов сущностей. Экземпляр
класса embeddable делает доступным тождественный объект, которым он владеет.
Классы embeddable существуют только как часть состояния другого объекта. В клас-
се embeddable объект может иметь простые атрибуты с одиночными значениями или атрибуты коллекции.
Классы embeddable имеют те же правила, как и классы сущностей, за исклю-
чением того, что они декорируются аннотацией javax.persistence.Embeddable вместо
@Entity.
Пример класса embeddable, где ZipCode имеет два поля — zip и plusFour:
@Embeddable
public class ZipCode {
118
String zip; String plusFour;
...
}
Этот класс embeddable используется объектом Address:
@Entity
public class Address {
@Id
protected long id String street1; String street2; String city; String province; @Embedded ZipCode zipCode; String country;
...
}
Объекты, которые обладают классами embeddable как частью их хранимого состояния, могут аннотировать поле или свойство javax.persitence.Embedded, но так де-
лать необязательно.
Классы embeddable могут сами использовать другие классы embeddable, чтобы представлять их состояние. Они могут также содержать коллекции основных типов языка программирования Java или других классов embeddable. Классы Embeddable могут также содержать ссылки на другие объекты или коллекции объектов. Если класс embeddable имеет такое отношение, то существует связь от целевого объекта или кол-
лекции объектов до объекта, который обладает классом embeddable.
11.4. Наследование сущностей
Сущности поддерживают наследование классов, полиморфные ассоциации и
полиморфные запросы. Они могут расширить несущностные классы, а некоторые не-
сущностные классы могут расширить сущностные классы. Классы сущностей могут быть как абстрактные, так и конкретные.
11.4.1. Абстрактные сущности
Абстрактный класс может быть объявлен сущностью аннотацией @Entity.
Абстрактные сущности отличаются от конкретных тем, что они не могут иметь экзем-
пляров.
Абстрактные сущности могут быть запрошены подобно конкретным объектам.
Если абстрактная сущность является целью запроса, запрос действует во всех кон-
кретных подклассах абстрактной сущности.
@Entity
public abstract class Employee {
@Id
protected Integer employeeId;
...
}
@Entity
119
public class FullTimeEmployee extends Employee { protected Integer salary;
...
}
@Entity
public class PartTimeEmployee extends Employee { protected Float hourlyWage;
}
11.4.2. Отображение суперклассов (Superclasses)
Сущности могут наследоваться от суперклассов, которые содержат хранимые
состояния и информацию об отображении, но не являются сущностями. То есть сам
суперкласс не аннотирован @Entity и не обозначен как сущность провайдеру Java Persistence. Эти суперклассы чаще всего используются, когда у вас есть состояние и
информация об отображении — общие для многих классов сущностей.
Отображение суперклассов определяется декоратором класса — аннотацией javax.persistence.MappedSuperclass.
@MappedSuperclass public class Employee {
@Id
protected Integer employeeId;
...
}
@Entity
public class FullTimeEmployee extends Employee { protected Integer salary;
...
}
@Entity
public class PartTimeEmployee extends Employee { protected Float hourlyWage;
...
}
Классы MappedSuperclass не могут использоваться в запросах, и их нельзя использовать в операциях EntityManager или Query. Вы должны использовать под-
классы сущности классов типа MappedSuperclass в операциях EntityManager или
Query. Отображенные суперклассы не могут быть объектами связи объекта. Классы MappedSuperclass могут быть абстрактными или конкретными.
Они не имеют соответствующих таблиц в базе данных. Объекты, которые на-
следуются от этих суперклассов, определяют соответствия таблиц. Например, в
коде, приведенном выше, основными таблицами являются FULLTIMEEMPLOYEE и
PARTTIMEEMPLOYEE, но не таблица EMPLOYEE.
11.4.3. Суперклассы без сущностей
Объекты могут иметь несущностные суперклассы, и эти суперклассы могут быть абстрактными или конкретными. Состояние несущностного суперкласса и любое со-
стояние унаследованного от несущностного суперкласса класса сущности — нехранимое. Несущностный суперкласс не может быть использован в операциях EntityManager
120
или Query. Любое отображение или аннотации отношения на несущностном суперклассе игнорируются.
11.5.Стратегии наследования сущностей с отображением
Вы можете конфигурировать провайдер Java Persistence, указав, как отобра-
жать унаследованные сущности в основное хранилище (datastore), декорируя корневой класс иерархии аннотаций javax.persistence.Inheritance. Есть три стратегии ото-
бражения сущностей в основной базе данных:
•единственная таблица на всю иерархию классов;
•таблица на конкретный класс сущностей;
•присоединяемая (join) стратегия, где поля или свойства для подкласса отображаются в одну таблицу, а поля или свойства, общие для родительского
класса, — в другую.
Стратегия конфигурируется установкой элемента strategy в аннотации
@Inheritance в одну из опций, определённых в перечислении javax.persistence.
InheritanceType:
public enum InheritanceType { SINGLE_TABLE,
JOINED, TABLE_PER_CLASS
};
Стратегия по умолчанию — InheritanceType.SINGLE_TABLE. Используется, если аннотация @Inheritance не определена в корневом классе иерархии сущностей.
11.5.1. Стратегия SingleTable
Стратегия SINGLE_TABLE отображает все классы в иерархии в единственную таблицу в базе данных. Эта таблица имеет столбец дискриминатора и столбец, со-
держащий значение, которое идентифицирует подкласс, которому принадлежит пред-
ставленный строкой экземпляр.
Столбец дискриминатора может быть определен использованием аннотации javax.persistence.DiscriminatorColumn (табл. 11.2) в корне иерархии классов сущностей.
|
|
Таблица 11.2 |
|
Элементы @DiscriminatorColumn |
|
|
|
|
Тип |
Имя |
Описание |
String |
name |
Имя столбца дискриминатора. По умолчанию — DTYPE. |
|
|
Этот элемент дополнительный. |
DiscriminatorType |
discriminatorType |
Тип столбца дискриминатора. По умолчанию — Discrimi- |
|
|
natorType.STRING. Этот элемент — дополнительный. |
String |
columnDefinition |
Фрагмент SQLдля создания столбца дискриминатора. |
|
|
По умолчанию генерируется провайдером и зависит от |
|
|
специфики реализации. Этот элемент — дополнительный. |
String |
length |
Длина столбца для строкового дискриминатора. Этот |
|
|
элемент игнорируется для нестроковых типов дискрими- |
|
|
натора. По умолчанию — 31. Этот элемент — дополни- |
|
|
тельный. |
121
Перечисление javax.persistence.DiscriminatorType используется для задания типа столбца дискриминатора в базе данных элементом discriminatorType в аннотации
@DiscriminatorColumn в один из определённых типов. DiscriminatorType определен следующим образом:
public enum DiscriminatorType { STRING,
CHAR,
INTEGER
};
Если @DiscriminatorColumn не определен в корне иерархии объекта и потребовался столбец дискриминатора, провайдером принимается по умолчанию имя столб-
ца DTYPE и типа столбца DiscriminatorType.STRING.
Аннотация javax.persistence.DiscriminatorValue может использоваться для уста-
новки значения в столбце дискриминатора для каждого объекта в иерархии класса. Вы можете декорировать конкретные классы объекта аннотацией @DiscriminatorValue.
Если @DiscriminatorValue не определен для сущности в иерархии класса, которая использует столбец дискриминатора, провайдер обеспечит по умолчанию специфическое для реализации значение. Если элемент discriminatorType в аннотации
@DiscriminatorColumn есть DiscriminatorType.STRING, то значением по умолчанию яв-
ляется имя объекта.
Эта стратегия обеспечивает хорошую поддержку для полиморфной связи между объектами и запросами, которая покрывает иерархию класса всех сущностей. Тем не менее, она требует использования столбцов, содержащих состояния подклассов, которые могут быть неопределёнными.
11.5.2.Стратегия TABLE_PER_CLASS
Вэтой стратегии, которая соответствует InheritanceType.TABLE_PER_CLASS, каждый конкретный класс отображен в отдельную таблицу в базе данных. Все области или свойства в классе, включая унаследованные области или свойства, отображены в столбцы таблицы в базе данных.
Эта стратегия обеспечивает слабую поддержку для полиморфной связи и обычно требует использования или запросов UNION, или отдельных запросов для каждого подкласса, которые покрывают иерархию всех классов сущностей.
Поддержка для этой стратегии — дополнительная и не может обеспечиваться
всеми провайдерами Java Persistence API. По умолчанию поставщик Java Persistence API на Enterprise Server (сервере предприятия) не поддерживает эту стратегию.
11.5.3.Стратегия JOINED
Вэтой стратегии, которая соответствует InheritanceType.JOINED, корень иерархии класса представлен единственной таблицей, и каждый подкласс имеет отдельную таблицу, которая содержит только специфические поля в этом подклассе. То есть таблица подкласса не содержит столбцов для наследованных полей или свойств. Таблица подкласса также имеет столбец или столбцы, представляющие свой первичный ключ, который является внешним ключом таблицы суперкласса.
Эта стратегия обеспечивает хорошую поддержку для полиморфной связи, но требует одной или более операций присоединения, которые нужно выполнять для экземпляров сущностей подкласса. Это может замедлить исполнение запросов для
122