Persistence Context Lifecycle
A persistence context is the first-level cache and unit of work that tracks managed entities during its lifecycle. In JPA, an entity moves among transient, managed, detached, and removed states as it interacts with an `EntityManager`.
A persistence context is the set of entity instances that a JPA `EntityManager` currently manages. For a given entity identity, the context normally maintains one managed Java object, allowing repeated lookups to reuse the same instance instead of creating another object from the database.
An entity becomes managed when it is associated with the persistence context, commonly through `persist()`, `find()`, or a query returning entities. While managed, changes to its persistent fields are tracked automatically by dirty checking; an explicit `update()` call is generally not required.
The persistence context ends or an entity leaves it when the context is cleared, closed, or the entity is detached. `clear()` detaches all managed entities, while `detach(entity)` removes one entity. A detached object can later be made managed again with operations such as `merge()`, which copies its state into a managed instance.
`remove()` marks a managed entity for deletion. The database change is normally synchronized during `flush`, which may occur explicitly or as part of transaction processing. The exact timing of SQL execution depends on the JPA provider and flush behavior, so application code should reason in terms of entity state and synchronization rather than assuming every operation immediately executes SQL.
Key points
- A persistence context is both a first-level cache and a unit of work.
- Managed entities are tracked automatically through dirty checking.
- `persist()` makes a new entity managed; `find()` can return a managed entity.
- `clear()` detaches all entities; `detach()` detaches one entity.
- `merge()` copies detached state into a managed instance; it does not simply reattach the same object.
- `remove()` marks a managed entity for deletion, with database synchronization occurring on flush.
Interview questions
What is a persistence context in JPA?
A persistence context is a set of entity instances managed by an `EntityManager`. It acts as a first-level cache and a unit of work. Managed entities are tracked for changes through dirty checking. The provider can later synchronize those changes with the database.
What are the common JPA entity lifecycle states?
The commonly discussed states are transient, managed, detached, and removed. A transient object has not been associated with a persistence context. A managed object is tracked by the context, while a detached object represents an entity that is no longer managed. A removed entity is managed but marked for deletion.
What is the difference between `persist()` and `merge()`?
`persist()` is used to make a new entity managed and is commonly used for a new object that should become persistent. `merge()` takes an entity's state and copies it into a managed instance. The object passed to `merge()` is not itself guaranteed to become managed. The return value of `merge()` is the instance that should be used as the managed reference.
What happens when you call `clear()` on an `EntityManager`?
`clear()` detaches all currently managed entities from the persistence context. Those Java objects are no longer automatically tracked for changes by that context. If their state must later be persisted, an appropriate operation such as `merge()` can copy their state into a managed instance. Clearing is also useful when processing large batches to limit the number of managed objects retained by the context.
When does JPA actually synchronize changes with the database?
Changes to managed entities are detected by dirty checking and synchronized with the database during a flush. A flush can be triggered explicitly with `flush()` or automatically according to the provider's flush behavior and transaction semantics. Flush is different from commit: flushing synchronizes pending persistence changes, while committing completes the transaction. Therefore, seeing a managed field change in Java does not necessarily mean an SQL statement has already been executed.