JPA @ManyToOne с каскадным типом.ВСЕ

Я думаю, что я неправильно понял значение каскадирования в контексте @ManyToOne отношения.

корпус:

public class User {

   @OneToMany(fetch = FetchType.EAGER)
   protected Set<Address> userAddresses;

}

public class Address {

   @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
   protected User addressOwner;

}

что означает cascade = CascadeType.ALL? Например, если я удаляю определенный адрес из базы данных, как это делает тот факт, что я добавил cascade = CascadeType.ALL влияет на мои данные (User, Я думаю)?

5 ответов


смысл CascadeType.ALL является то, что настойчивость будет распространяться (каскад) все EntityManager операции (PERSIST, REMOVE, REFRESH, MERGE, DETACH) для связанных объектов.

кажется, в вашем случае это плохая идея, как удаление Address приведет к удалению соответствующих User. Поскольку у пользователя может быть несколько адресов, другие адреса станут сиротами. Однако обратный случай (аннотирование User) имело бы смысл - если адрес принадлежит только одному пользователю, безопасно распространять удаление всех адресов, принадлежащих Пользователю, если этот пользователь удален.

BTW: вы можете добавить mappedBy="addressOwner" атрибут User сигнализировать поставщику персистентности, что столбец соединения должен быть в адресной таблице.


посмотреть здесь для примера из документов OpenJPA. CascadeType.ALL означает, что он будет делать все действия.

цитата:

CascadeType.PERSIST: при сохранении сущности также сохраняются сущности, содержащиеся в этом поле. Мы предлагаем либеральное применение этого правила каскада, потому что если EntityManager находит поле, которое ссылается на новый объект во время flush, и поле не использует CascadeType.Упорствуйте, это ошибка.

CascadeType.Удалить: при удалении сущности также удалите сущности, содержащиеся в этом поле.

CascadeType.Обновить: при обновлении сущности также обновите сущности, содержащиеся в этом поле.

CascadeType.Слияние: при слиянии состояния сущности также объединяйте сущности, содержащиеся в этом поле.

Себастьян


от EJB3.0 спецификация:

для распространения влияние операции на связанные объекты. Каскад функциональность чаще всего используется в отношениях родитель-потомок.

если X-управляемый объект, операция удаления приводит к тому, что он становится удаленный. Операция удаления каскадируется на объекты, на которые ссылается X, если отношения от X к этим другим сущностям аннотируется значение элемента аннотации cascade=REMOVE или cascade=ALL.

Итак, в двух словах, отношения сущностей, определенные с CascadeType.All гарантирует, что все события сохраняемости, такие как persist, refresh, merge и remove, которые происходят на родителе, будут переданы дочернему. Определение других CascadeType options предоставляет разработчику более детальный уровень контроля над тем, как ассоциация сущностей обрабатывает сохраняемость.

например, если бы у меня был объектная книга, содержащая список страниц, и я добавляю объект страницы в этот список. Если @OneToMany аннотация, определяющая связь между книгой и страницей, помечается как CascadeType.All, сохранение книги приведет к тому, что страница также будет сохранена в базе данных.


как я объяснил в в этой статье и в моей книге, Высокая Производительность Java Persistence, вы никогда не должны использовать CascadeType.ALL on @ManyToOne С сущность состояния должен распространяться от родительских объектов к дочерним.

на @ManyToOne сторона всегда является дочерней ассоциацией, так как она должна отображать базовый FK.

, перемещение CascadeType.ALL с

в JPA 2.0, Если вы хотите удалить адрес, если вы удалили его из сущности пользователя, вы можете добавить orphanRemoval=true (вместо CascadeType.REMOVE) к @OneToMany.

больше объяснений между orphanRemoval=true и CascadeType.REMOVE is здесь.