··private String description;
··private String isbn;
··private Integer nbOfPage;
··private Boolean illustrations;
··@ElementCollection(fetch = FetchType.LAZY)
··@CollectionTable(name = "Tag")
··@Column(name = "Value")
··private List
··// Конструкторы, геттеры, сеттеры
}
Аннотация @ElementCollection, показанная в листинге 5.24, используется для информирования поставщика постоянства о том, что атрибут tags представляет собой список строк, а его выборка должна быть отложенной. При отсутствии @CollectionTable имя таблицы по умолчанию было бы BOOK_TAGS (конкатенация имени содержащей сущности и имени атрибута коллекции, разделенных знаком подчеркивания), а не TAG, как указано в элементе name (name = "Tag"). Обратите внимание, что я добавил дополнительную аннотацию @Column, чтобы переименовать столбец в VALUE (в противном случае этот столбец получил бы имя, как у атрибута, TAGS). Результат можно увидеть на рис. 5.2.
Рис. 5.2. Связь между таблицами BOOK и TAG
В JPA 1.0 этих аннотаций не было. Однако все равно можно было сохранить список примитивных типов, например BLOB, в базе данных. Почему? А потому, что java.util.ArrayList реализует Serializable, а JPA может автоматически отображать сериализуемые объекты в BLOB-объекты. Вместе с тем, если вы взамен используете тип java.util.List, то получите исключение, так как он не расширяет Serializable. Применение @ElementCollection — более элегантный и целесообразный способ сохранения списков базовых типов. Сохранение списков в недоступном двоичном формате не позволит совершать к ним запросы и сделает их непереносимыми в код на других языках (поскольку основной сериализованный объект может быть использован во время выполнения кода, написанного только на Java — не на Ruby, PHP…).
Отображение базовых типов
Как и коллекции, отображения очень полезны при сохранении данных. В JPA 1.0 ключи могли относиться только к базовому типу данных, а значения могли быть только сущностями. Сейчас отображения могут содержать любую комбинацию базовых типов, встраиваемых объектов и сущностей как ключей или значений, что привносит б
Когда отображение задействует базовые типы, аннотации @ElementCollection и @CollectionTable могут быть использованы тем же путем, который вы видели ранее в случае с коллекциями. Таблица коллекции тогда будет использоваться для хранения данных отображения.
Обратимся к примеру с CD-альбомом, содержащим треки (листинг 5.25). Трек имеет название и позицию (первый трек альбома, второй трек альбома и т. д.). Тогда у вас может быть отображение треков с целочисленным значением, говорящем о позиции определенного трека (ключ отображения), и строкой для указания названия этого трека (значение отображения).
@Entity
public class CD {
··@Id @GeneratedValue
··private Long id;
··private String title;
··private Float price;
··private String description;
··@Lob
··private byte[] cover;
··@ElementCollection
··@CollectionTable(name="track")
··@MapKeyColumn (name = "position")
··@Column(name = "title")
··private Map
··// Конструкторы, геттеры, сеттеры
}
Я уже говорил, что аннотация @ElementCollection используется как индикатор объектов в отображении, хранящихся в таблице коллекции. Аннотация @CollectionTable изменяет имя по умолчанию таблицы коллекции на TRACK.