DEV Community

Cover image for 💀 I Deleted a Parent Entity… and Hibernate Deleted Everything (Cascades Explained)
Shashwath S H
Shashwath S H

Posted on

💀 I Deleted a Parent Entity… and Hibernate Deleted Everything (Cascades Explained)

When I started working with Spring Data JPA relationships, I thought saving and deleting was simple:

repository.save(parent);
Enter fullscreen mode Exit fullscreen mode

Or:

repository.delete(parent);
Enter fullscreen mode Exit fullscreen mode

Then I tried it with relationships like:

  • Patient → Appointments
  • User → Orders
  • Department → Employees

And suddenly…

✅ Saving one object saved many
💀 Deleting one object deleted many
❌ Updates didn’t behave how I expected

That’s when I learned the two concepts that control everything:

✅ Cascade Types
✅ @Transactional


🧠 What is Cascading in JPA?

In JPA, cascading tells Hibernate:

“When I perform an operation on the parent, automatically apply it to the child entities too.”

So instead of manually doing:

  • save parent
  • save child
  • save child
  • save child

Hibernate can do it for you.


🔁 Common Cascade Types (and what they really mean)

✅ CascadeType.PERSIST

When you save the parent, child entities are saved automatically.

Use case: parent creation should create children too.


✅ CascadeType.MERGE

When you update the parent, related child updates propagate.

Use case: parent update should sync children.


💀 CascadeType.REMOVE

When you delete the parent, child entities are deleted too.

Use case: child has no meaning without parent (like appointments without patient).

⚠️ This is the one that can wipe data if used blindly.


✅ CascadeType.REFRESH

Reloads child entities when parent is refreshed.


✅ CascadeType.DETACH

Detaches child entities when parent is detached from persistence context.


✅ CascadeType.ALL

Applies all cascade operations:
PERSIST, MERGE, REMOVE, REFRESH, DETACH

This feels convenient — but it can be dangerous if you don’t understand it.


🧹 The Hidden Killer: orphanRemoval = true

This is not a cascade type, but it changes deletion behavior massively.

orphanRemoval = true means:

If a child is removed from the parent collection, Hibernate deletes it from the database automatically.

Example:

  • Parent remains in DB ✅
  • Child removed from list ❌ → deleted from DB 💀

✅ Cascade REMOVE vs orphanRemoval (Important Difference)

CascadeType.REMOVE

Child is deleted only when parent is deleted.

orphanRemoval = true

Child is deleted when it is no longer referenced by parent, even if parent is still alive.

This is perfect for true parent-child lifecycle relationships.


🔥 Why @Transactional Becomes Important in Relational Queries

At first I thought transactions are only for big systems.

But relational operations break easily without a transaction because:

  • multiple DB operations happen in one flow
  • entity states change during execution
  • lazy loading may fail outside a session

That’s why Spring provides @Transactional.


🧠 What does @Transactional do?

@Transactional ensures that all operations inside a method run in one transaction.

That means:

  • Either everything succeeds ✅
  • Or everything rolls back ❌

This makes database operations safe and consistent.


⚠️ What Happens Without @Transactional?

This is where people get errors like:

  • partial save (half data inserted, half failed)
  • inconsistent state
  • lazy-loading issues (accessing relations after session closes)

Even if your code looks correct, database behavior becomes unpredictable.


✅ Real-World Scenario: Saving Parent + Children

If you have:

  • Patient has many Appointments

and you set:

  • cascade = PERSIST or ALL

Then:
✅ Saving Patient automatically saves Appointments
✅ No need to explicitly save Appointment records

This keeps code clean and avoids repeated repository calls.


✅ Final Thoughts

Cascading and transactions are not “extra JPA features”.

They decide whether your application is:

  • clean ✅
  • scalable ✅
  • safe ✅ or
  • unpredictable ❌
  • dangerous ❌
  • bug-prone ❌

If you’re using Spring Data JPA relationships, you can’t ignore:
✅ Cascade Types
✅ orphanRemoval
✅ @Transactional

This post is part of my learning-in-public journey while exploring Spring Boot and real-world backend behavior.

Have you ever deleted a parent entity and lost child data by mistake? 😅

Top comments (0)