JPA @ManyToOne с CascadeType.ALL

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

Случай:

 public class User { @OneToMany(fetch = FetchType.EAGER) protected Set
userAddresses; } public class Address { @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) protected User addressOwner; }

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

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

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

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

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

    Цитата:

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

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

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

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

    Себастьян

    Из спецификации EJB3.0 :

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

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

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

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

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

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

    Поэтому переместите CascadeType.ALL из ассоциации @ManyToOne в @OneToMany которая должна использовать атрибут mappedBy поскольку это наиболее эффективное сопоставление «один ко многим» . `

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

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

    Давайте будем гением компьютера.