What Cascade Types Exist
JPA provides several cascade operation types, each controlling the propagation of a specific operation type to related entities. Choosing the right cascade type is key to correc...
Overview
JPA provides several cascade operation types, each controlling the propagation of a specific operation type to related entities. Choosing the right cascade type is key to correctly working with object graphs.
Junior Level
All CascadeType Types
CascadeType.ALL - all operations (persist, merge, remove, refresh, detach)
CascadeType.PERSIST - on persist(parent) -> persist(child)
CascadeType.MERGE - on merge(parent) -> merge(child)
CascadeType.REMOVE - on remove(parent) -> remove(child)
CascadeType.REFRESH - on refresh(parent) -> refresh(child)
CascadeType.DETACH - on detach(parent) -> detach(child)
Example of Each
// PERSIST - saving with children
@OneToMany(cascade = CascadeType.PERSIST)
private List<OrderItem> items;
entityManager.persist(order); // -> persist for all items
// MERGE - updating with children
@OneToMany(cascade = CascadeType.MERGE)
private List<OrderItem> items;
entityManager.merge(order); // -> merge for all items
// REMOVE - deleting with children
@OneToMany(cascade = CascadeType.REMOVE)
private List<OrderItem> items;
entityManager.remove(order); // -> remove for all items
// ALL - all operations
@OneToMany(cascade = CascadeType.ALL)
private List<OrderItem> items;
When NOT to Use Cascade at All
Don’t use cascade when both entities are aggregate roots with their own lifecycle. For example, Order and Customer are separate aggregates, cascading between them is dangerous.
Middle Level
When to Use What
@OneToMany (composite): CascadeType.ALL + orphanRemoval = true
@ManyToOne: CascadeType.PERSIST, MERGE (or no cascade)
@OneToOne: CascadeType.ALL
@ManyToMany: CascadeType.PERSIST, MERGE
Composite vs Association
// Composite - child doesn't exist without parent
@Entity
public class Order {
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderItem> items; // OrderItem without Order has no meaning
}
// Association - entities are independent
@Entity
public class Order {
@ManyToOne // no cascade
private User user; // User exists independently of Order
}
Common Mistakes
// Cascade.REMOVE for shared entities
@ManyToOne(cascade = CascadeType.REMOVE)
private User user;
entityManager.remove(order); // User also deleted!
// Cascade.ALL for @ManyToOne
@ManyToOne(cascade = CascadeType.ALL)
private Category category;
entityManager.remove(product); // Category deleted!
// Without cascade for shared
@ManyToOne
private User user; // User managed separately
Senior Level
Advanced Scenarios
// Scenario 1: Cascade PERSIST + MERGE for @ManyToOne
@Entity
public class Order {
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
// Code smell: cascading from Order to User - shared entity.
// May accidentally create duplicate users.
// Cascading PERSIST/MERGE from child to parent is an antipattern.
private User user;
}
// New User will be saved with Order
User newUser = new User();
Order order = new Order();
order.setUser(newUser);
entityManager.persist(order); // -> persist User, persist Order
// Existing User will be merged
order.setUser(existingUser);
entityManager.merge(order); // -> merge User, merge Order
Cascading and Validation
@Entity
public class Order {
@Valid // Bean Validation cascade. @Valid is Hibernate Validator (Hibernate-specific), not JPA standard. Validation fires on persist/merge.
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> items;
}
// On persist/merge - validation for all items
entityManager.persist(order); // -> validation for Order + all items
Production Patterns
// Pattern 1: Order -> OrderItem (composite)
@Entity
public class Order {
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderItem> items = new ArrayList<>();
public void addItem(OrderItem item) {
items.add(item);
item.setOrder(this);
}
}
// Pattern 2: Order -> User (shared)
@Entity
public class Order {
@ManyToOne // no cascade
private User user;
}
// Pattern 3: User -> Address (composite)
@Entity
public class User {
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Address> addresses = new ArrayList<>();
}
Decision Matrix
| Association | Cascade | orphanRemoval | Why |
|---|---|---|---|
| @OneToMany (composite) | ALL | true | Child doesn’t exist without parent |
| @ManyToOne (shared) | PERSIST, MERGE | false | Entity managed separately |
| @OneToOne (composite) | ALL | true | One-to-one, composition |
| @ManyToMany | PERSIST, MERGE | false | Shared entities, dangerous to delete |
Best Practices
ALL for composite children
PERSIST, MERGE for shared entities
Without REMOVE for shared entities
orphanRemoval for composite children
Decision matrix for each association
REMOVE for shared entities
ALL for @ManyToOne
Cascade.REMOVE in Many-to-Many
Without understanding composite/association difference
Interview Cheat Sheet
Must know:
- 6 CascadeType types: ALL, PERSIST, MERGE, REMOVE, REFRESH, DETACH
- ALL - all operations, but dangerous for @ManyToOne and Many-to-Many
- Compositions (Order -> OrderItem): CascadeType.ALL + orphanRemoval = true
- Associations (Order -> User): PERSIST, MERGE or no cascade
- @ManyToOne with cascade PERSIST/MERGE from child to parent - antipattern (duplicates)
- Decision matrix: each association gets its own cascade, not universal
Frequent follow-up questions:
- Why is @ManyToOne with cascade a code smell? Cascading from Order to User may create duplicate users
- What is composite vs association? Composite - child doesn’t exist without parent (OrderItem), association - independent entities (User)
- Can cascade types be combined? Yes: cascade = {CascadeType.PERSIST, CascadeType.MERGE}
- When is cascade not needed at all? When entities are managed separately via their own repositories
Red flags (DO NOT say):
- “CascadeType.ALL for all associations” - REMOVE deletes shared entities
- “Cascade.REMOVE for @ManyToOne” - deleting Order deletes User
- “Cascade.ALL for Many-to-Many” - deleting Author deletes all Books
- “I don’t understand composite/association difference” - critical for cascade choice
Related topics:
- [[20. How Do Cascade Operations Work]]
- [[22. What is Orphan Removal]]
- [[23. How to Properly Use @OneToMany and @ManyToOne]]
- [[24. What Are the Peculiarities of Bidirectional Relationships]]