JPA Cascade Types and orphanRemoval — When to Use Each
Fast recall
Quick revision
Core answer
persist, merge, remove, refresh, detach) from a parent to its children. `PERSIST` — saving the parent saves new children. `MERGE` — merging the parent merges children. `REMOVE` — deleting the parent deletes all children (catastrophic on `@ManyToMany` because it deletes shared entities). `ALL` combines all five. `orphanRemoval = true` is a stricter, collection-level trigger — it fires whenever a child is removed from the collection, even if the parent still exists. Distinction: cascade REMOVE deletes children when the parent is deleted; orphanRemoval deletes children when removed from the collection OR when parent is deleted. Safe default for owned @OneToMany: cascade = {PERSIST, MERGE}, orphanRemoval = true. Never cascade REMOVE across `@ManyToMany`.Whether the candidate understands the difference between cascade REMOVE and orphanRemoval, and when each is appropriate
Using `CascadeType.ALL` on `@ManyToMany` — deleting one student cascades to delete courses, which cascades to delete other students enrolled
Explain orphanRemoval as collection-level ON DELETE CASCADE, the ghost-entity bug from MERGE, and the cascade decision tree by relationship type
Interview-ready guide
Interview answer
Cascade types propagate JPA operations from a parent to its associated children. Choosing the wrong one is one of the easiest ways to delete data unintentionally.
What each cascade does:
- PERSIST — saving the parent saves new children
- MERGE — merging the parent merges children
- REMOVE — deleting the parent deletes children
- REFRESH — refreshing the parent re-loads children
- ALL — all of the above
The `@ManyToMany` REMOVE trap:
@ManyToMany(cascade = REMOVE)onStudent.coursesdeletes the courses themselves- Other students lose those courses too — catastrophic
- Never cascade REMOVE or ALL across
@ManyToMany
`orphanRemoval = true`:
- Collection-level ON DELETE CASCADE
order.getItems().remove(item)triggers DELETE on the item- Also fires when parent is deleted
- Only works on the owning side with
mappedByor@JoinColumn
Safe defaults:
- Owned children ->
cascade = {PERSIST, MERGE}, orphanRemoval = true - Shared children -> no cascade or
PERSIST, MERGEonly - Junction entities ->
cascade = ALL, orphanRemoval = true @ManyToOne-> almost never cascade
JPA Cascade Types and `orphanRemoval` — When to Use Each
Direct Answer
JPA cascade types propagate entity lifecycle operations (persist, merge, remove, refresh, detach) from a parent to its children. PERSIST — saving the parent saves new children. MERGE — merging the parent merges children. REMOVE — deleting the parent deletes all children (catastrophic on @ManyToMany because it deletes shared entities). ALL combines all five. orphanRemoval = true is a stricter, collection-level trigger — it fires whenever a child is removed from the collection, even if the parent still exists. Distinction: cascade REMOVE deletes children when the parent is deleted; orphanRemoval deletes children when removed from the collection OR when parent is deleted. Safe default for owned @OneToMany: cascade = {PERSIST, MERGE}, orphanRemoval = true. Never cascade REMOVE across @ManyToMany.
Common Mistakes & Pitfalls
Using CascadeType.ALL on @ManyToMany — deleting one student cascades to delete courses, which cascades to delete other students enrolled
Check your understanding
Answer these without looking back at the article.
- What is the ghost entity bug, and why does `MERGE` cause it?
- Why doesn't `orphanRemoval` work on a unidirectional `@OneToMany` with a join table?
- When is `cascade = ALL` actually safe?
- How do you delete a parent without cascading to shared children?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.