Entity Lifecycle and States
Entity Lifecycle and States
JPA entities go through distinct states during their lifetime. Understanding these states is critical for writing correct persistence code, especially when working with detached entities in web applications or batch jobs.
The Four Entity States
+--------------------+
| Transient |
| (new, not saved) |
+---------+----------+
|
entityManager.persist()
|
v
+--------------------+ merge() +--------------------+
| Managed | ----------------> | Detached |
| (tracked by ORM) | <---------------- | (was managed, |
+---------+----------+ find() or | now disconnected) |
| refresh() +--------------------+
|
entityManager.remove()
|
v
+--------------------+
| Removed |
| (marked for delete)|
+--------------------+
|
flush() / commit()
|
v
+--------------------+
| (deleted from |
| database) |
+--------------------+
Transient
A transient entity is a plain Java object that has no connection to the database. You created it with new, but you have not called persist() yet. The ORM does not track it at all.
// Transient - just created, not in DB
Book book = new Book("Effective Java", "Joshua Bloch", "978-0134685991", 45.00);
// book has no ID yet if using IDENTITY strategy
Managed
After calling entityManager.persist(book), the entity becomes managed. Hibernate now tracks all changes to it. When you call flush() or the transaction commits, Hibernate automatically generates the appropriate SQL (INSERT, UPDATE, or DELETE).
// Managed - persisted to DB and tracked by Hibernate
entityManager.persist(book);
book.setPrice(42.00); // This change will be auto-flushed as an UPDATE
Detached
An entity becomes detached when the EntityManager closes or when you explicitly clear the persistence context. The entity still has data but Hibernate no longer tracks changes. In a typical web app, entities returned from a service method are often detached by the time the view layer renders them.
// Detached - outside the persistence context
entityManager.detach(book);
book.setPrice(50.00); // This change is NOT tracked
// Re-attach with merge()
Book reattached = entityManager.merge(book); // reattached is now managed
Removed
Calling entityManager.remove(book) marks the entity for deletion. The actual DELETE SQL runs on flush or commit. The entity object still exists in memory but is no longer usable for queries.
entityManager.remove(book);
// The DELETE SQL will execute when the transaction commits
Key Points
- Transient entities exist in memory but are not connected to the database.
- Managed entities are tracked by the persistence context; changes auto-flush.
- Detached entities were once managed but are no longer tracked.
- Removed entities are marked for deletion and removed on flush or commit.
merge()re-attaches a detached entity and returns a new managed copy.