Loading published curriculum…

14 · Hibernate and Spring Data JPA in depth / LESSON 67 OF 102

Cascade, orphan removal, and many-to-many design

Deletion propagation should follow aggregate ownership, not convenience.

Before this lesson: Many-to-one, one-to-many, and relationship ownership

Understand the topic

CascadeType.REMOVE can delete related entities; it is dangerous on shared references such as an owner or tag. orphanRemoval deletes a child removed from its owning aggregate relationship. Use it only where the child lifecycle genuinely belongs to the parent.

A many-to-many join table is sufficient for a pure association. When the relationship gains attributes such as assignedAt or role, model an explicit join entity. Shared tags should survive deleting one task.

EXAMPLE · JAVA

Aggregate mapping fragment

// In a Project entity whose Task children are exclusive to it.
@OneToMany(mappedBy = "project", cascade = CascadeType.ALL, orphanRemoval = true)
private java.util.List<Task> tasks = new java.util.ArrayList<>();

public void remove(Task task) {
 tasks.remove(task);
 task.setProject(null);
}

What to expect

Requires Task.project plus its setter and consistent entity identity. Removing a managed child schedules orphan deletion at flush. Do not copy this lifecycle policy onto shared tags.

YOUR TURN

Put it into practice

  1. 01Model project-owned tasks and shared tags separately.
  2. 02Delete a project and then remove one task-tag association while inspecting affected rows.
  3. 03Verify: Owned children follow the chosen lifecycle while shared tags remain intact.

Pass a quiz or complete a lab to check today’s streak. Each lesson counts once per day, including when you review it later.

UNDER THE HOOD

Build the mental model

Deletion propagation should follow aggregate ownership, not convenience.

  1. 01CascadeType.REMOVE can delete related entities; it is dangerous on shared references such as an owner or tag. orphanRemoval deletes a child removed from its owning aggregate relationship. Use it only where the child lifecycle genuinely belongs to the parent.
  2. 02A many-to-many join table is sufficient for a pure association. When the relationship gains attributes such as assignedAt or role, model an explicit join entity. Shared tags should survive deleting one task.
  3. 03Trace the example: Requires Task.project plus its setter and consistent entity identity. Removing a managed child schedules orphan deletion at flush. Do not copy this lifecycle policy onto shared tags.

A mistake worth avoiding

Deleting one task unexpectedly deletes a shared category.

DEBUGGING ROOM

Something broke. Where do you look?

Deleting one task unexpectedly deletes a shared category.

Before revealing the diagnosis, write down your first investigation step.

CHECK YOUR UNDERSTANDING

Is cascade REMOVE safe by default on a shared many-to-many target?

Choose one answer

BUILD IT YOURSELF

Model project-owned tasks and shared tags separately.

  1. 1.Model project-owned tasks and shared tags separately.
  2. 2.Delete a project and then remove one task-tag association while inspecting affected rows.
  3. 3.Reproduce this failure, then repair it: Deleting one task unexpectedly deletes a shared category.

Acceptance checklist

Lab completion is your self-report. Knowledge checks do not certify project quality.

RETRIEVE IT FROM MEMORY

Is cascade REMOVE safe by default on a shared many-to-many target?

Revisit this lesson in three days after a successful check or lab.

Ready for the next step?

Owned children follow the chosen lifecycle while shared tags remain intact.

Reading is separate from passing a knowledge check or completing a lab.

Go deeper · official references