Detached Entity State in JPA

A detached entity retains its database identity but is no longer managed by the current JPA persistence context. Changes made while detached are not automatically tracked or synchronized with the database.

JPA entities commonly move through transient, managed, detached, and removed states. An entity becomes managed when it is associated with an active persistence context, typically through `persist()`, `find()`, or a query result.

An entity becomes detached when its association with the persistence context ends. This can happen when the context is cleared or closed, when `detach()` is called, or when an entity is returned after its transaction and persistence context have ended.

A detached entity still represents a row identity, so its identifier is normally available. However, JPA no longer performs dirty checking for it, meaning changing a field on the detached object does not by itself cause an SQL `UPDATE`.

To make a detached instance managed again, an application can use `EntityManager.merge()`. `merge()` copies the state of the detached object into a managed instance; it does not simply reattach the same Java object. The returned object is the managed instance that should normally be used for subsequent changes.

Key points

Interview questions

What is a detached entity in JPA?

A detached entity is an entity that was previously associated with a persistence context but is no longer managed by it. It normally retains its identifier and represents existing persistent data. Because it is not managed, JPA does not automatically detect changes made to it. If its state needs to be persisted again, it can be merged into a persistence context.

How can an entity become detached?

An entity can become detached when the persistence context is cleared or closed, or when `EntityManager.detach()` is explicitly called. In application code, this can also occur when an entity leaves the scope of a persistence context associated with a transaction. The important point is that the object remains in memory while its management relationship with the context ends.

What happens when you call `merge()` on a detached entity?

`merge()` copies the state of the supplied entity into a managed entity associated with the current persistence context. The supplied detached instance itself does not become the managed instance. The method returns the managed instance, which should be used for subsequent operations. Changes to that returned object can then participate in dirty checking.

Why are changes to a detached entity not automatically persisted?

JPA performs dirty checking for entities managed by a persistence context. Once an entity is detached, that context no longer tracks its field changes. Therefore, modifying the detached object alone does not cause an update during flush. The state must first be incorporated into a managed entity, commonly with `merge()`.

What is a common mistake when using `merge()` with a detached entity?

A common mistake is assuming that calling `merge(detached)` makes `detached` itself managed. Instead, `merge()` returns a managed instance containing the appropriate state. Continuing to modify the original detached object will not make those later changes part of the managed instance. Code should generally retain and use the object returned by `merge()`.