Изучаем Java EE 7 - [76]

Шрифт
Интервал

>····inverseJoinColumns = @JoinColumn(name = "order_line_fk"))

>··private List orderLines;

>··// Конструкторы, геттеры, сеттеры

>}

В случае с API-интерфейсом аннотации @JoinTable в листинге 5.42 вы можете видеть два атрибута типа @JoinColumn: joinColumns и inverseJoinColumns. Они различаются владеющей и противоположной сторонами. Элемент joinColumns характеризует владеющую сторону (владельца связи) и в нашем примере ссылается на таблицу ORDER. Элемент inverseJoinColumns определяет противоположную сторону, то есть цель связи, и ссылается на ORDER_LINE.

При использовании сущности Order (листинг 5.44) вы можете добавить аннотации @OneToMany и @JoinTable для атрибута orderLines, переименовав таблицу соединения в JND_ORD_LINE (вместо ORDER_ORDER_LINE), а также два столбца внешнего ключа.

Сущность Order из листинга 5.44 будет отображена в таблицу соединения, описанную в листинге 5.45.


Листинг 5.45. Структура таблицы соединения между ORDER и ORDER_LINE

>create table JND_ORD_LINE (

>··ORDER_FK BIGINT not null,

>··ORDER_LINE_FK BIGINT not null,

>··primary key (ORDER_FK, ORDER_LINE_FK),

>··foreign key (ORDER_LINE_FK) references ORDER_LINE(ID),

>··foreign key (ORDER_FK) references ORDER(ID)

>);

Правило по умолчанию для однонаправленной связи «один ко многим» — использование таблицы соединения, однако его очень легко (и целесообразно, если речь идет об унаследованных базах данных) изменить таким образом, чтобы применялись внешние ключи. Для сущности Order необходимо предусмотреть аннотацию @JoinColumn вместо @JoinTable, что позволит изменить код, как показано в листинге 5.46.


Листинг 5.46. Сущность Order наряду со столбцом соединения

>@Entity

>public class Order {

>··@Id @GeneratedValue

>··private Long id;

>··@Temporal(TemporalType.TIMESTAMP)

>··private Date creationDate;

>··@OneToMany(fetch = FetchType.EAGER)

>··@JoinColumn(name = "order_fk")

>··private List orderLines;

>··// Конструкторы, геттеры, сеттеры

>}

Код сущности OrderLine (показанной в листинге 5.46) не изменится. Обратите внимание, что в листинге 5.46 аннотация @OneToMany переключает режим по умолчанию fetch (поменяв LAZY на EAGER). При использовании вами @JoinColumn стратегия внешнего ключа затем обеспечивает отображение однонаправленной связи. Внешний ключ переименовывается с помощью аннотации в ORDER_FK и располагается в целевой таблице (ORDER_LINE). В результате получается структура базы данных, показанная на рис. 5.17. Таблица соединения отсутствует, а ссылка между обеими таблицами осуществляется по внешнему ключу ORDER_FK.


Рис. 5.17. Столбец соединения между ORDER и ORDER_LINE


Двунаправленная связь с использованием @ManyToMany

Двунаправленная связь «многие ко многим» имеет место, когда один объект-источник ссылается на много целей и когда цель ссылается на много источников. Например, CD-альбом создается несколькими артистами, а один артист принимает участие в создании нескольких CD-альбомов. В мире Java у каждой сущности будет коллекция целевых сущностей. В реляционном мире единственный способ отобразить связь «многие ко многим» — использовать таблицу соединения (столбец соединения не поможет). Кроме того, как вы уже видели ранее, при двунаправленной связи вам потребуется явным образом определить владельца (с помощью элемента mappedBy).

Если исходить из того, что сущность Artist является владельцем связи, то это будет означать, что противоположным владельцем (листинг 5.47) выступает сущность CD, которой необходимо, чтобы элемент mappedBy был использован в сочетании с ее аннотацией @ManyToMany. Элемент mappedBy сообщит поставщику постоянства о том, что appearsOnCDs — это имя соответствующего атрибута владеющей сущности.


Листинг 5.47. Несколько артистов приняли участие в создании одного CD-альбома

>@Entity

>public class CD {

>··@Id @GeneratedValue

>··private Long id;

>··private String title;

>··private Float price;

>··private String description;

>··@ManyToMany(mappedBy = "appearsOnCDs")

>··private List createdByArtists;

>··// Конструкторы, геттеры, сеттеры

>}

Таким образом, если сущность Artist является владельцем связи, как показано в листинге 5.48, то она будет использоваться для настройки отображения таблицы соединения посредством аннотаций @JoinTable и @JoinColumn.


Листинг 5.48. Один артист принял участие в создании нескольких CD-альбомов

>@Entity

>public class Artist {

>··@Id @GeneratedValue

>··private Long id;

>··private String firstName;

>··private String lastName;

>··@ManyToMany

>··@JoinTable(name = "jnd_art_cd", 

>····joinColumns = @JoinColumn(name = "artist_fk"), 

>····inverseJoinColumns = @JoinColumn(name = "cd_fk"))

>··private ListappearsOnCDs;

>··// Конструкторы, геттеры, сеттеры

>}

Как вы можете видеть в листинге 5.48, таблица соединения между Artist и CD переименовывается в JND_ART_CD, как и каждый столбец соединения (благодаря аннотации @JoinTable). Элемент joinColumns ссылается на владеющую сторону (Artist), а inverseJoinColumns — на противоположную владеющую сторону (CD). Соответствующая структура базы данных показана на рис. 5.18.


Рис. 5.18. ARTIST, CD и таблица соединения


Следует отметить, что при двунаправленной связи «многие ко многим» и «один к одному» любая из сторон может быть обозначена как владеющая. Независимо от того, какая из сторон будет обозначена как владелец, владеющая сторона должна включать элемент mappedBy. В противном случае поставщик будет считать, что обе стороны являются владельцами, и воспринимать все это как две отдельные однонаправленные связи «один ко многим». В результате этого могло бы получиться четыре таблицы: ARTIST и CD плюс две таблицы соединения с именами ARTIST_CD и CD_ARTIST. И недопустимым было бы наличие mappedBy на обеих сторонах.


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.