По умолчанию любая операция выполняется менеджером сущностей только в отношении сущности, которая предусмотрена в качестве аргумента при этой операции. Но порой, когда операция выполняется в отношении сущности, возникает необходимость распространить ее на соответствующие ассоциации. Это называется каскадированием события. Приводившиеся до сих пор примеры опирались на поведение каскадирования по умолчанию, а не на настроенное поведение. В листинге 6.17 показано, что для создания Customer нужно сгенерировать экземпляры сущностей Customer и Address, связать их (customer.setAddress(address)), а затем обеспечить постоянство этих двух экземпляров.

Листинг 6.17. Обеспечение постоянства Customer и Address

Customer customer = new Customer("Энтони", "Балла", "tballa@mail.com");

Address address = new Address("Ризердаун Роуд", "Лондон", "8QE", "Англия");

customer.setAddress(address);

tx.begin();

em.persist(customer);

em.persist(address);

tx.commit();

Поскольку между Customer и Address есть связь, вы могли бы каскадировать действие persist от Customer к Address. Это означало бы, что вызов em.persist(customer) привел бы к каскадированию события PERSIST к сущности Address, если она допускает распространение события такого типа. Тогда вы могли бы сократить код и избавиться от em.persist(address), как показано в листинге 6.18.

Листинг 6.18. Каскадирование события PERSIST к Address

Customer customer = new Customer("Энтони", "Балла", "tballa@mail.com");

Address address = new Address("Ризердаун Роуд", "Лондон", "8QE", "Англия");

customer.setAddress(address);

tx.begin();

em.persist(customer);

tx.commit();

Без каскадирования было бы обеспечено постоянство Customer, но не Address. Каскадирование события возможно при изменении отображения связи. У аннотаций @OneToOne, @OneToMany, @ManyToOne и @ManyToMany есть атрибут cascade, который принимает массив событий для каскадирования, а также событие PERSIST, которое можно каскадировать, как и событие REMOVE (широко используемое для выполнения каскадных удалений). Для этого вам потребуется изменить отображение сущности Customer (листинг 6.19) и добавить атрибут cascade в аннотацию @OneToOne в случае с Address.

Листинг 6.19. Сущность Customer и каскадирование событий PERSIST и REMOVE

@Entity

public class Customer {

@Id @GeneratedValue

··private Long id;

··private String firstName;

··private String lastName;

··private String email;

··@OneToOne (fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.REMOVE})

··@JoinColumn(name = "address_fk")

··private Address address;

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

}

Вы можете выбирать из нескольких событий для каскадирования к цели ассоциации (эти события приведены в табл. 6.3) и даже каскадировать их все, используя тип CascadeType.ALL.

Таблица 6.3. Возможные события для каскадирования
CascadeTypeОписание
PERSISTКаскадирует операции по обеспечению постоянства к цели ассоциации
REMOVEКаскадирует операции удаления к цели ассоциации
MERGEКаскадирует операции объединения к цели ассоциации
REFRESHКаскадирует операции обновления к цели ассоциации
DETACHКаскадирует операции отсоединения к цели ассоциации
ALLОбъявляет, что должны быть каскадированы все предыдущие операции
<p>JPQL</p>
Перейти на страницу:

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