Як працюють каскадні операції (Cascade)
Cascading (каскадування) в JPA — механізм автоматичного поширення операцій, що виконуються над батьківською сутністю, на всі пов'язані з нею дочірні сутності. Це дозволяє управл...
Огляд
Cascading (каскадування) в JPA — механізм автоматичного поширення операцій, що виконуються над батьківською сутністю, на всі пов’язані з нею дочірні сутності. Це дозволяє управляти цілими графами об’єктів через один виклик методу EntityManager.
🟢 Junior Level
Що таке Cascade
Cascade — автоматично поширює операції з батьківської сутності на пов’язані.
@Entity
public class Order {
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> items;
}
Order order = new Order();
OrderItem item = new OrderItem();
order.getItems().add(item);
entityManager.persist(order); // persist викличеться і для items!
CascadeTypes
CascadeType.ALL — всі операції (persist, merge, remove, refresh, detach)
CascadeType.PERSIST — тільки persist
CascadeType.MERGE — тільки merge
CascadeType.REMOVE — тільки remove
CascadeType.REFRESH — тільки refresh
CascadeType.DETACH — тільки detach
🟡 Middle Level
Cascade vs orphanRemoval
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderItem> items;
// Cascade — propagates операції (persist, merge, remove)
// orphanRemoval — видаляє entities які видалені з колекції
order.getItems().remove(0); // orphanRemoval видалить item з БД!
// Ключова відмінність: CascadeType.REMOVE спрацьовує тільки при видаленні батька.
// orphanRemoval спрацьовує також при видаленні дитини з колекції,
// навіть якщо батько не видалений.
Рекомендації щодо використання
@OneToMany (composite): CascadeType.ALL + orphanRemoval = true
@ManyToOne: CascadeType.PERSIST, MERGE (або без cascade)
@OneToOne: CascadeType.ALL
@ManyToMany: CascadeType.PERSIST, MERGE
Типові помилки
// ❌ Cascade.ALL для @ManyToOne
@ManyToOne(cascade = CascadeType.ALL)
private User user;
// При видаленні Order → видалиться User!
entityManager.remove(order); // ❌ cascade.REMOVE → User видалено
// ✅ Без cascade для shared entities
@ManyToOne
private User user; // User управляється окремо
JPA Cascade vs DB Cascade
JPA Cascading:
- Виконується кодом Hibernate
- Hibernate повинен знати про всі об'єкти в пам'яті
- Зручно для об'єктно-орієнтованої логіки
DB Cascading (ON DELETE CASCADE):
- Виконується рушієм СУБД
- Відбувається швидше
- Гарантує цілісність при прямих SQL запитах
🔴 Senior Level
Внутрішня реалізація
Cascade process:
1. При операції на parent (persist, merge, remove)
2. Hibernate обходить всі пов'язані entities
3. Для кожного child — застосовує операцію
4. Рекурсивно для nested зв'язків
5. Всі операції scheduled в persistence context
6. При flush — виконуються в правильному порядку
Каскадування в Many-to-Many
// ❌ Cascade.REMOVE в Many-to-Many — небезпечно!
@Entity
public class Author {
@ManyToMany(cascade = CascadeType.ALL)
private List<Book> books;
}
// Видалення Author → видалення всіх книг → видалення інших Authors
// Видалення Author з cascade=ALL видалить всі Books цього автора.
// Якщо у Books теж є cascade=ALL до Author — видалиться і другий автор, і його книги.
// ✅ Без REMOVE для Many-to-Many
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Book> books;
Best Practices
✅ CascadeType.ALL для композицій (child не має сенсу без parent)
✅ PERSIST, MERGE для асоціацій (shared entities)
✅ orphanRemoval для composite children
✅ Без REMOVE для shared entities
✅ DB-level cascade для великих видалень
❌ CascadeType.ALL для @ManyToOne
❌ Cascade.REMOVE для shared entities
❌ Cascade.REMOVE в Many-to-Many
❌ Каскадне видалення великих колекцій через JPA
🎯 Шпаргалка для співбесіди
Обов’язково знати:
- Cascade автоматично поширює операції (persist, merge, remove) на пов’язані сутності
- CascadeType.ALL — всі операції, PERSIST/MERGE/REMOVE — окремі типи
- CascadeType.ALL для композицій (Order → OrderItem), PERSIST/MERGE для асоціацій (Order → User)
- Cascade.REMOVE для @ManyToOne — небезпечно: видалення Order видалить User
- Каскади JPA працюють тільки з Managed-об’єктами
Пов’язані теми:
- [[21. Які типи Cascade існують]]
- [[22. Що таке orphan removal]]
- [[23. Як правильно використовувати @OneToMany і @ManyToOne]]
- [[7. Опишіть життєвий цикл Entity в Hibernate]]