Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2013_1 / КСТ / Разработка веб-приложений.pdf
Скачиваний:
160
Добавлен:
23.02.2015
Размер:
2.74 Mб
Скачать

 

Таблица 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

Соседние файлы в папке КСТ