Разница в случае с коллекциями заключается во введении новой аннотации: @MapKeyColumn. Она используется для указания отображения ключевого столбца. Если она не будет задана, то столбец получит имя в виде конкатенации имени ссылающегося атрибута связи и _KEY. В листинге 5.25 видно, что аннотация переименовала его в POSITION, чтобы было яснее, а по умолчанию он назывался бы иначе (TRACK_KEY).
Аннотация @Column указывает на то, что столбец, содержащий значение отображения, следует переименовать в TITLE. Результат можно увидеть на рис. 5.3.
Рис. 5.3. Связь между таблицами CD и TRACK
Теперь, когда вы ближе познакомились с элементарным отображением с использованием аннотаций, взглянем на XML-отображение. Если вам доводилось применять объектно-реляционный фреймворк вроде ранних версий Hibernate, то вы уже знаете, как отображать свои сущности в отдельном файле XML-дескриптора развертывания. С начала этой главы вы не видели ни одной строки XML-кода, а только аннотации. JPA также предлагает как вариант XML-синтаксис для отображения сущностей. Я не стану вдаваться в подробности XML-отображения, поскольку решил сосредоточиться на аннотациях (так как их легче использовать в книге, а большинство разработчиков выбирает их вместо XML-отображения). Имейте в виду, что у каждой аннотации, которую вы увидите в текущей главе, имеется XML-эквивалент, а этот раздел получился бы огромным, если бы я рассмотрел в нем их все. Я рекомендую вам заглянуть в главу 12 под названием «XML-дескриптор объектно-реляционного отображения» спецификации JPA 2.1, где более детально рассматриваются все XML-теги.
XML-дескрипторы развертывания — альтернатива применению аннотаций. Однако, несмотря на то что у каждой аннотации есть эквивалентный XML-тег и наоборот, разница состоит в том, что XML берет верх над аннотациями. Если вы аннотируете атрибут или сущность с использованием определенного значения и в то же время произведете развертывание XML-дескриптора с использованием другого значения, то преимущество будет за XML.
Вопрос звучит так: когда вам следует использовать аннотации вместо XML и почему? Прежде всего, это дело вкуса, поскольку оба ведут себя абсолютно одинаково. Когда метаданные действительно связаны с кодом (например, речь может идти о первичном ключе), имеет смысл использовать аннотации, поскольку метаданные являются лишь еще одним аспектом программы. Прочие виды метаданных, например длина столбца или другие детали схемы, могут быть изменены в зависимости от среды развертывания (скажем, схема базы данных может отличаться в среде разработки, тестирования или производства). Похожая ситуация возникает, когда основанному на JPA продукту необходимо обеспечить поддержку баз данных от нескольких разных поставщиков. Может потребоваться настроить генерирование определенного идентификатора, параметра столбца и т. д. в зависимости от типа используемой базы данных. Это может быть лучше выражено во внешних XML-дескрипторах развертывания (по одному на среду), благодаря чему код не придется модифицировать.
Снова обратимся к примеру сущности Book. На этот раз представьте, что у вас имеется две среды и вы желаете отобразить сущность Book в таблицу BOOK в среде разработки и в таблицу BOOK_XML_MAPPING в среде тестирования. Класс будет аннотирован только с помощью @Entity (листинг 5.26) и не станет включать информацию о таблице, в которую его надлежит отобразить (то есть аннотация @Table будет отсутствовать). Аннотация @Id определяет первичный ключ как генерируемый автоматически, а аннотация @Column задает длину описания равной 500 символам.
@Entity
public class Book {
··@Id @GeneratedValue
··private Long id;
··private String title;
··private Float price;
··@Column(length = 500)
··private String description;
··private String isbn;
··private Integer nbOfPage;
··private Boolean illustrations;
··// Конструкторы, геттеры, сеттеры
}