JPA merge Semantics
`merge` copies the state of a detached or transient entity into a managed instance; it does not make the object passed to `merge` managed. The returned entity is the managed instance that should be used for subsequent persistence operations.
In JPA, `EntityManager.merge(entity)` transfers the state of the supplied entity into an entity with the same persistent identity in the current persistence context. If a managed instance already exists, its state is updated; otherwise, the provider may obtain or create a managed instance representing that identity.
The crucial distinction is the return value. The argument remains detached if it was detached, while the object returned by `merge` is managed. Therefore, code that modifies the original object after merging should not assume those changes are automatically tracked.
`merge` can also accept a transient entity. In that case, the provider creates a managed instance and copies the supplied state into it; the resulting entity becomes subject to persistence according to the entity's mapping and lifecycle rules. The exact SQL emitted depends on the provider, mappings, identifier strategy, and flush behavior.
Because merging copies state, associations matter. Cascade settings such as `CascadeType.MERGE` determine whether merge propagates to related entities. Without appropriate cascade configuration, an associated object is not necessarily merged simply because the owning entity is merged.
After calling merge, prefer working with the returned reference inside the active persistence context. This avoids confusing the detached source object with the managed copy and makes dirty checking behavior explicit.
Key points
- `merge` copies entity state into a managed instance.
- The object passed to `merge` does not become managed.
- The returned object is the managed reference.
- Merge can be used with detached and transient entities.
- Association propagation depends on cascade configuration such as `CascadeType.MERGE`.
Interview questions
What happens if an entity with the same identity is already managed?
The provider merges the supplied state into the existing managed instance rather than introducing a second managed instance with the same persistent identity. This preserves the persistence context's identity guarantee. The returned value is the managed instance whose state now reflects the merge operation. The exact database interaction is governed by flush behavior and provider implementation details.
What does `EntityManager.merge()` actually do?
It copies the state of the supplied entity into a managed entity in the current persistence context. The supplied object itself does not become managed. The method returns the managed instance containing the merged state. This is why callers should normally use the returned reference for subsequent changes.
Why is `entity = entityManager.merge(entity)` a common pattern?
The variable initially refers to the detached or transient object. `merge` returns the managed instance into which that object's state was copied. Reassigning the variable makes subsequent modifications operate on the managed object. Without reassignment, later changes to the original object are not automatically tracked by the persistence context.
How does `merge` differ from `persist`?
`persist` is intended to make a new entity managed and schedules it for insertion. `merge` is designed to copy state from a detached or transient object into a managed instance. With `persist`, the supplied entity becomes managed; with `merge`, the supplied entity does not become managed. The important practical difference is therefore both lifecycle semantics and how the returned reference is used.
What role does `CascadeType.MERGE` play?
Merge cascades to an association only when the relationship mapping includes an appropriate merge cascade. With `CascadeType.MERGE`, the provider propagates the merge operation to the associated entity. Without it, merging the parent does not automatically mean that the associated object's state is merged. This is particularly important for detached object graphs.