JPA Entity Lifecycle States
Fast recall
Quick revision
Core answer
EntityManager methods: `persist()` makes Transient become Managed, `remove()` marks Managed as Removed, `merge()` copies a Detached entity into a new Managed instance (the original stays Detached — always assign the return value), and the persistence context boundary (transaction commit) detaches everything. Hibernate uses automatic dirty checking at flush time — comparing the entity to its load-time snapshot — so you never call an explicit update().Core JPA knowledge — understanding of the persistence context and when Hibernate detects and flushes dirty changes
Confusing Detached and Removed, or not knowing that `merge()` returns a new managed instance rather than making the passed object managed
Discuss the persistence context as a first-level cache, automatic dirty-checking at flush time, and how Spring's `@Transactional` scope determines when entities become detached
Interview-ready guide
Interview answer
Every JPA entity exists in one of four states at any given moment. The state determines whether changes are tracked, persisted, or ignored.
The four states:
- Transient —
new Order()— not associated with anyEntityManager; changes have no effect on the database - Managed — inside a transaction after
em.persist()orem.find(); Hibernate tracks every field change and flushes them as SQL on commit - Detached — after the transaction ends or
em.detach()is called; entity object exists but changes are ignored; mustem.merge()to reattach - Removed — after
em.remove(); DELETE is issued on flush
Dirty checking:
- Hibernate takes a snapshot of each Managed entity's state when loaded
- On flush, it compares current state to the snapshot and generates UPDATE SQL for changed fields
- No
em.update()call needed — just modify the field on a Managed entity
Entity lifecycle callbacks:
@PrePersist— fires before INSERT; good forcreatedAttimestamps@PreUpdate— fires before UPDATE; good forupdatedAt@PostLoad— fires after every load from database or L2 cache@PreRemove— fires before DELETE
The big gotcha: merge() returns the managed copy; the argument stays Detached. Always assign the return value back to your variable.
JPA Entity Lifecycle States
Direct Answer
A JPA entity moves through four states: Transient (new, not tracked), Managed (inside a persistence context, dirty-checked), Detached (existed in DB but session closed — changes silently lost), and Removed (scheduled for DELETE). Transitions are driven by EntityManager methods: persist() makes Transient become Managed, remove() marks Managed as Removed, merge() copies a Detached entity into a new Managed instance (the original stays Detached — always assign the return value), and the persistence context boundary (transaction commit) detaches everything. Hibernate uses automatic dirty checking at flush time — comparing the entity to its load-time snapshot — so you never call an explicit update().
Common Mistakes & Pitfalls
Confusing Detached and Removed, or not knowing that merge() returns a new managed instance rather than making the passed object managed
Check your understanding
Answer these without looking back at the article.
- What is the difference between `save()` and `saveAndFlush()` in Spring Data JPA?
- How does Hibernate perform dirty checking — does it use `equals`/`hashCode` or something else?
- What happens if you call `em.merge()` on a transient entity (one that has no id)?
- How do `cascade=PERSIST` and `cascade=MERGE` differ in practice?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.