DEV Community

Cover image for 🧠 Hibernate Felt Like Magic… Until I Understood Entity Lifecycle & Cascading
Shashwath S H
Shashwath S H

Posted on

🧠 Hibernate Felt Like Magic… Until I Understood Entity Lifecycle & Cascading

At first, Spring Data JPA felt amazing.

I wrote:

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

Data magically appeared in the database.

But then strange things started happening.

  • Updates didn’t persist
  • Deletes didn’t behave as expected
  • Child records disappeared (or didn’t)
  • Entities acted… alive

That’s when I realized:

👉 I didn’t understand what Hibernate was actually doing.


🏗️ The Big Stack (Clear Mental Model)

Before diving deep, here’s the actual hierarchy:

👉 Spring Data JPA → abstraction (repositories)
👉 JPA → specification (rules)
👉 Hibernate → implementation (ORM engine)
👉 JDBC → executes SQL
👉 Database

Spring JPA

Spring Data JPA reduces boilerplate.
Hibernate does the heavy lifting.
JDBC talks to the database.


🧬 Hibernate Entity Lifecycle (The Missing Piece)

Every JPA entity lives in one of these states.

Understanding this changed everything for me.


🟡 Transient

Patient p = new Patient();
Enter fullscreen mode Exit fullscreen mode
  • Just a Java object
  • Not tracked by Hibernate
  • Not stored in DB

If garbage collected → gone forever.


🟢 Persistent

Triggered by:

  • persist()
  • save()
  • find()
  • get() / load()

Now:

  • Entity is managed
  • Tracked inside Persistence Context
  • Changes are auto-synced to DB

👉 This is where Hibernate magic happens.


🔵 Detached

Triggered by:

  • detach()
  • clear()
  • close()

Entity:

  • Exists in DB
  • Exists in memory
  • But Hibernate stops tracking it

Changes won’t be saved unless you merge().


🔴 Removed

Triggered by:

  • remove()
  • delete()

Entity:

  • Marked for deletion
  • Deleted during transaction commit

Entity Lifecycle


🧠 EntityManager & Persistence Context (VERY IMPORTANT)

VERY IMPORTANT

Hibernate doesn’t hit the DB immediately.

It first checks the Persistence Context.

Flow:

  1. find() → checks Persistence Context
  2. If found → return object
  3. If not → DB SELECT
  4. Store entity in Persistence Context

👉 This is why multiple finds don’t always hit the DB.


🔗 Relationships: Owning Side vs Inverse Side

This is where many bugs are born.

🔑 Owning Side

  • Controls the foreign key
  • Updates actually affect DB

🔄 Inverse Side

  • Only reflects relationship
  • Cannot update foreign key

👉 Updating inverse side alone does nothing in DB.


🏥 One-to-Many Example (Patient & Appointments)

  • Patient = Parent
  • Appointment = Child

If Patient is deleted → Appointments should also go.

That’s why:
👉 Patient is the owning lifecycle controller


🔁 Cascading: Let Hibernate Do the Work

Cascading tells Hibernate:

“When I do something to the parent, do the same to children.”

Common Cascade Types:

  • PERSIST → save child automatically
  • MERGE → update child
  • REMOVE → delete child
  • REFRESH
  • DETACH
  • ALL

Example:

  • Save Patient → Appointments saved automatically
  • Delete Patient → Appointments deleted automatically

No manual repository calls needed.


🧹 orphanRemoval = true (POWERFUL & DANGEROUS)

This one surprised me.

What it does:

  • Deletes child entity when it’s removed from parent collection
  • Parent still exists

Example:

patient.getAppointments().remove(appointment);
Enter fullscreen mode Exit fullscreen mode

👉 Appointment gets deleted from DB automatically.


orphanRemoval vs CascadeType.REMOVE

Feature CascadeType.REMOVE orphanRemoval
Parent deleted ✅ Child deleted ✅ Child deleted
Child removed from collection
Parent still exists

🎯 When to Use orphanRemoval

Perfect when:

  • Child has no meaning without parent
  • Appointment without Patient
  • Insurance without User

⚠️ Use carefully — deletions are automatic.


⚠️ The Mistakes I Was Making

I used to:

  • Call save() everywhere
  • Ignore entity states
  • Manually delete children
  • Get confused by unexpected deletes

Once I understood:

  • Entity lifecycle
  • Persistence Context
  • Cascades & orphanRemoval

👉 Hibernate stopped feeling random.


🚀 Final Thoughts

Hibernate is not magic.

It’s state + rules + lifecycle.

If JPA ever feels:

  • Unpredictable
  • Dangerous
  • Confusing

You’re missing this layer of understanding.

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

Did Hibernate ever delete or update something you didn’t expect?

Top comments (0)