АннотацияОписание
@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))

······throw new IllegalArgumentException("Неверное имя");

····if (lastName == null || "".equals(lastName))

······throw new IllegalArgumentException("Неверная фамилия");

··}

··@PostLoad

··@PostPersist

··@PostUpdate

Перейти на страницу:

Похожие книги