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

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

Эта аннотация принимает два возможных значения — FIELD или PROPERTY, а также может быть использована в отношении сущности как таковой и/или каждого атрибута или геттера. Например, при применении @Access(AccessType.FIELD) к сущности поставщиком постоянства будут приниматься во внимание только аннотации отображения, которыми снабжены атрибуты. Тогда можно будет выборочно обозначить отдельные геттеры для доступа к свойствам посредством @Access(AccessType.PROPERTY).

Типы явного доступа могут быть очень полезны (например, при работе со встраиваемыми объектами или наследованием), однако их смешение часто приводит к ошибкам. В листинге 5.23 показан пример того, что может произойти при смешении типов доступа.


Листинг 5.23. Сущность Customer, в случае с которой явным образом смешиваются типы доступа

>@Entity

>@Access(AccessType.FIELD)

>public class Customer {

>··@Id @GeneratedValue

>··private Long id;

>··@Column(name = "first_name", nullable = false, length = 50)

>··private String firstName;

>··@Column(name = "last_name", nullable = false, length = 50)

>··private String lastName;

>··private String email;

>··@Column(name = "phone_number", length = 15)

>··private String phoneNumber;

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

>··@Access(AccessType.PROPERTY)

>··@Column(name = "phone_number", length = 555)

>··public String getPhoneNumber() {

>····return phoneNumber;

>··}

>··public void setPhoneNumber(String phoneNumber) {

>····this.phoneNumber = phoneNumber;

>··}

>}

В примере, показанном в листинге 5.23, тип доступа явным образом определяется как FIELD на уровне сущности. Это говорит интерфейсу PersistenceManager о том, что ему следует обрабатывать только аннотации, которыми снабжены атрибуты. Атрибут phoneNumber снабжен аннотацией @Column, ограничивающей значение его length величиной 15. Читая этот код, вы ожидаете, что в базе данных в итоге будет VARCHAR(15), однако этого не случится. Метод-геттер показывает, что тип доступа для метода getPhoneNumber() был изменен явным образом, поэтому длина равна значению length атрибута phoneNumber (до 555). В данном случае сущность AccessType.FIELD перезаписывается AccessType.PROPERTY. Тогда в базе данных у вас окажется VARCHAR(555).

Коллекции базовых типов

Коллекции тех или иных элементов очень распространены в Java. Из последующих разделов вы узнаете о связях между сущностями (которые могут быть коллекциями сущностей). По сути, это означает, что у одной сущности имеется коллекция других сущностей или встраиваемых объектов. Что касается отображения, то каждая сущность отображается в свою таблицу, при этом создаются ссылки между первичными и внешними ключами. Как вы уже знаете, сущность представляет собой Java-класс с идентификатором и множеством других атрибутов. Но что, если вам потребуется сохранить коллекцию Java-типов, например String или Integer? С тех пор как вышла версия JPA 2.0, это можно легко сделать без необходимости решать проблему создания отдельного класса. Для этого предназначены аннотации @ElementCollection и @CollectionTable.

Мы используем аннотацию @ElementCollection как индикатор того, что атрибут типа java.util.Collection включает коллекцию экземпляров базовых типов (то есть объектов, которые не являются сущностями) или встраиваемых объектов (подробнее на эту тему мы поговорим в разделе «Встраиваемые объекты»). Фактически этот атрибут может иметь один из следующих типов:

• java.util.Collection — общий корневой интерфейс в иерархии коллекций;

• java.util.Set — коллекция, предотвращающая вставку элементов-дубликатов;

• java.util.List — коллекция, которая применяется, когда требуется извлечь элементы в некоем порядке, определяемом пользователем.

Кроме того, аннотация @CollectionTable позволяет вам настраивать детали таблицы коллекции (то есть таблицы, которая будет соединять таблицу сущности с таблицей базовых типов), например изменять ее имя. При отсутствии этой аннотации имя таблицы будет конкатенацией имени содержащей сущности и имени атрибута коллекции, разделенных знаком подчеркивания.

Опять-таки, используя сущность-пример Book, взглянем на то, как добавить атрибут для сохранения тегов. Сегодня теги и облака тегов распространены повсеместно. Они обычно применяются при сортировке данных, поэтому представим в этом примере, что вы хотите добавить как можно больше тегов сущности Book для ее описания и быстрого поиска. Тег — это всего лишь строка, так что у сущности Book может быть коллекция строк для сохранения соответствующей информации, как показано в листинге 5.24.


Листинг 5.24. Сущность Book с коллекцией строк

>@Entity

>public class Book {

>··@Id @GeneratedValue

>··private Long id;

>··private String title;

>··private Float price;

>··private String description;

>··private String isbn;

>··private Integer nbOfPage;

>··private Boolean illustrations;

>··@ElementCollection(fetch = FetchType.LAZY)

>··@CollectionTable(name = "Tag")

>··@Column(name = "Value")

>··private List tags = new ArrayList<>();

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

>}

Аннотация @ElementCollection, показанная в листинге 5.24, используется для информирования поставщика постоянства о том, что атрибут tags представляет собой список строк, а его выборка должна быть отложенной. При отсутствии @CollectionTable имя таблицы по умолчанию было бы BOOK_TAGS (конкатенация имени содержащей сущности и имени атрибута коллекции, разделенных знаком подчеркивания), а не TAG, как указано в элементе name (name = "Tag"). Обратите внимание, что я добавил дополнительную аннотацию @Column, чтобы переименовать столбец в VALUE (в противном случае этот столбец получил бы имя, как у атрибута, TAGS). Результат можно увидеть на рис. 5.2.


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