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

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

Во многих примерах в этой книге сущности ничего не реализуют, однако если им потребуется пересечь сеть при удаленном вызове или пересечь уровни для вывода на уровне представления, то им потребуется реализовать интерфейс java.io.Serializable. Это не JPA-, а Java-ограничение. Когда находящаяся под управлением сущность сериализуется, пересекает сеть и десериализуется, она рассматривается как отсоединенный объект. Чтобы снова присоединить сущность, вам потребуется вызвать метод EntityManager.merge(). Распространенный сценарий использования — вариант, когда сущность задействуется в JSF-странице. Допустим, сущность Customer выводится в форме на удаленной JSF-странице, подлежащей обновлению. Будучи удаленной, сущность нуждается в сериализации на стороне сервера перед отправкой на уровень представления. В тот момент сущность автоматически отсоединяется. После вывода, если какие-либо данные изменятся и их понадобится обновить, форма будет отправлена, а сущность — отослана обратно на сервер, десериализована. Она потребует слияния, чтобы снова присоединиться.

Методы обратного вызова и слушатели позволяют вам добавлять собственную бизнес-логику, когда с сущностью происходят определенные события жизненного цикла.

Обратные вызовы

Операции, выполняемые с сущностями во время их жизненного цикла, подпадают под четыре категории: обеспечение постоянства, обновление, удаление и загрузка. При этом они аналогичны категориям операций с базами данных, к которым относятся соответственно вставка, обновление, удаление и выборка. Во время каждого жизненного цикла имеют место события с приставками pre и post, которые могут быть перехвачены менеджером сущностей для вызова бизнес-метода. Такие бизнес-методы должны быть снабжены одной из аннотаций, описанных в табл. 6.7. Эти аннотации могут применяться к методам класса-сущности, отображенного суперкласса или класса-слушателя обратных вызовов.


Таблица 6.7. Аннотации обратных вызовов жизненного цикла
АннотацияОписание
@PrePersistПомечает метод для вызова до выполнения EntityManager.persist()
@PostPersistПомечает метод для вызова после того, как будет обеспечено постоянство сущности. Если сущность будет автоматически генерировать свой первичный ключ (с использованием @GeneratedValue), то значение окажется доступно в соответствующем методе
@PreUpdateПомечает метод для вызова до выполнения операции обновления в отношении базы данных (путем вызова сеттеров сущности или метода EntityManager.merge())
@PostUpdateПомечает метод для вызова после выполнения операции обновления в отношении базы данных
@PreRemoveПомечает метод для вызова до выполнения EntityManager.remove()
@PostRemoveПомечает метод для вызова после того, как сущность будет удалена
@PostloadПомечает метод для вызова после того, как сущность будет загружена (посредством JPQL-запроса или EntityManager.find()) либо обновлена из основной базы данных. Аннотации @Preload не существует, поскольку в предварительной загрузке данных для сущности, которая еще не создана, нет смысла

Результатом добавления аннотаций обратных вызовов в UML-диаграмму состояний, показанную на рис. 6.6, является диаграмма, которую можно увидеть на рис. 6.7.

Перед вставкой сущности в базу данных менеджер сущностей вызывает метод, снабженный аннотацией @PrePersist. Если вставка не приведет к генерированию исключения, то будет обеспечено постоянство сущности, инициализирован ее идентификатор, а затем вызван метод, снабженный аннотацией @PostPersist. Аналогичное поведение наблюдается при операциях обновления (@PreUpdate, @PostUpdate) и удаления (@PreRemove, @PostRemove). Метод, аннотированный с использованием @PostLoad, вызывается после загрузки сущности из базы данных (посредством EntityManager.find() или JPQL-запроса). Когда сущность отсоединяется и требуется произвести ее слияние, менеджер сущностей сначала должен проверить, имеются ли какие-либо отличия от информации, содержащейся в базе данных (@PostLoad). Если да, то ему надлежит обновить данные (@PreUpdate, @PostUpdate).


Рис. 6.7. Жизненный цикл сущности с аннотациями обратных вызовов


Как все это выглядит в коде? Сущности могут включать не только атрибуты, конструкторы, геттеры и сеттеры, но и бизнес-логику, используемую для валидации их состояния или выполнения вычислений для некоторых их атрибутов. Сюда могут входить обычные Java-методы, вызываемые другими классами, или аннотации обратных вызовов (которые также называются методами обратного вызова), как показано в листинге 6.38. Менеджер сущностей вызывает их автоматически в зависимости от инициируемого события.


Листинг 6.38. Сущность Customer с аннотациями обратных вызовов

>@Entity

>public class Customer {

>··@Id @GeneratedValue

>··private Long id;

>··private String firstName;

>··private String lastName;

>··private String email;

>··private String phoneNumber;

>··@Temporal(TemporalType.DATE)

>··private Date dateOfBirth;

>··@Transient

>··private Integer age;

>··@Temporal(TemporalType.TIMESTAMP)

>··private Date creationDate;


>··@PrePersist

>··@PreUpdate

>··private void validate() {

>····if (firstName == null || "".equals(firstName))


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