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)