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

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


Рис. 5.13. Код Customer и Address наряду с отображением базы данных


На рис. 5.13 в аннотации @OneToOne сущности Address используется элемент mappedBy. Address в данном случае именуется противоположным владельцем связи, поскольку обладает элементом mappedBy. Элемент mappedBy говорит о том, что столбец соединения (address) указан на другом конце связи. Кроме того, на другом конце связи сущность Customer определяет столбец соединения путем использования аннотации @JoinColumn и переименовывает внешний ключ в address_fk. Сущность Customer представляет собой владеющую сторону связи и, как владелец, должна определять отображение столбца соединения. Address выступает в качестве противоположной стороны связи, где таблица владеющей сущности содержит внешний ключ (таблица CUSTOMER включает столбец ADDRESS_FK).

Элемент mappedBy может присутствовать в аннотациях @OneToOne, @OneToMany и @ManyToMany, но не в @ManyToOne. Атрибут mappedBy не может быть сразу на обеих сторонах двунаправленной ассоциации. Было бы также неправильно, если бы его не было ни на одной из сторон, поскольку поставщик воспринимал бы все это как две независимые однонаправленные связи. Это подразумевало бы, что каждая из сторон является владельцем и может определять столбец соединения.


Примечание

Если вы знакомы с более ранними версиями Hibernate, то можете представлять себе JPA-параметр mappedBy как эквивалент Hibernate-атрибута inverse.


Однонаправленная связь с использованием @OneToOne

Однонаправленная связь «один к одному» между сущностями имеет ссылку кардинальности 1, которая досягаема только в одном направлении. Обратившись к примеру клиента и его домашнего адреса, предположим, что у него имеется только один домашний адрес (кардинальность 1). Важно выполнить навигацию от Customer (источник) по направлению к Address (цель), чтобы узнать, где клиент живет. Однако по некоторым причинам при нашей модели, показанной на рис. 5.14, вам не потребуется возможность навигации в противоположном направлении (например, вам не будет нужно знать, какой клиент живет по определенному адресу).


Рис. 5.14. У одного клиента имеется один домашний адрес


В Java однонаправленная связь означает, что у Customer будет иметься атрибут Address (листинг 5.35), однако у Address не будет атрибута Customer (листинг 5.36).


Листинг 5.35. Customer с одним Address

>@Entity

>public class Customer {

>··@Id @GeneratedValue

>··private Long id;

>··private String firstName;

>··private String lastName;

>··private String email;

>··private String phoneNumber;

>··private Address address;

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

>}


Листинг 5.36. Сущность Address

>@Entity

>public class Address {

>··@Id @GeneratedValue

>··private Long id;

>··private String street1;

>··private String street2;

>··private String city;

>··private String state;

>··private String zipcode;

>··private String country;

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

>}

Как вы можете видеть в листингах 5.35 и 5.36, эти две сущности снабжены минимально необходимыми нотациями: @Entity с @Id и @GeneratedValue для первичного ключа и все. При использовании конфигурации в порядке исключения поставщик постоянства отобразит эти две сущности в две таблицы, а также внешний ключ для связи (из customer, указывающего на address). Отображение «один к одному» инициируется тем фактом, что Address является объявленной сущностью и включает сущность Customer как атрибут. Мы автоматически предполагаем связь, используя одну сущность как свойство другой, поэтому нам не нужна аннотация @OneToOne, поскольку она опирается на правила по умолчанию (листинги 5.37 и 5.38).


Листинг 5.37. Таблица CUSTOMER с внешним ключом к ADDRESS

>create table CUSTOMER (

>··ID BIGINT not null,

>··FIRSTNAME VARCHAR(255),

>··LASTNAME VARCHAR(255),

>··EMAIL VARCHAR(255),

>··PHONENUMBER VARCHAR(255),

>··ADDRESS_ID BIGINT,

>··primary key (ID),

>··foreign key (ADDRESS_ID) references ADDRESS(ID)

>);


Листинг 5.38. Таблица ADDRESS

>create table ADDRESS (

>··ID BIGINT not null,

>··STREET1 VARCHAR(255),

>··STREET2 VARCHAR(255),

>··CITY VARCHAR(255),

>··STATE VARCHAR(255),

>··ZIPCODE VARCHAR(255),

>··COUNTRY VARCHAR(255),

>··primary key (ID)

>);

Как вы уже знаете, при использовании JPA, если не аннотировать атрибут, будут применены правила отображения по умолчанию. Таким образом, изначально внешний ключ будет носить имя ADDRESS_ID (листинг 5.37), которое представляет собой конкатенацию имени атрибута связи (здесь это address), символа «_» и имени столбца первичного ключа целевой таблицы (здесь им будет идентификатор столбца таблицы ADDRESS). Обратите также внимание, что в DDL-коде столбец ADDRESS_ID по умолчанию является nullable, а это означает, что ассоциация «один к одному» отображается в нуль (значение null) или единицу.

Для настройки отображения вы можете использовать две аннотации. Первая — @OneToOne (поскольку кардинальность отношения равна единице). Она позволяет модифицировать отдельные атрибуты ассоциации как таковой, например, подход, посредством которого должна осуществляться ее выборка. В листинге 5.39 определен API-интерфейс аннотации @OneToOne.


Листинг 5.39. API-интерфейс аннотации @OneToOne

Рекомендуем почитать
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 так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.