EntityManager.persist() and the JPA Entity Lifecycle

`EntityManager.persist()` makes a new entity instance managed by the persistence context and marks it for insertion. The database `INSERT` normally occurs later, such as during transaction flush or commit, rather than necessarily when `persist()` is called.

`persist()` is used for a new JPA entity that should become part of the current persistence context. After the call, the entity is in the managed state, so changes to it can be tracked automatically by the persistence provider.

The operation is normally performed inside an active transaction. JPA does not require the SQL `INSERT` to execute immediately when `persist()` runs; the provider can defer SQL until the persistence context is flushed. A flush may happen explicitly through `flush()` or automatically at appropriate transaction boundaries according to the configured flush behavior.

Once managed, changing a persistent field usually does not require another `persist()` call. At flush time, the provider detects relevant changes and synchronizes them with the database. This is one reason the persistence context is central to JPA's unit-of-work model.

`persist()` is different from `merge()`. `persist()` is intended to make a new entity managed, while `merge()` copies the state of a detached or other entity instance into a managed instance. A common interview point is that the object returned by `merge()` is the managed instance; the original argument should not be assumed to become managed.

If an entity is already managed, calling `persist()` again generally has no additional effect. Passing an entity that violates the operation's lifecycle expectations can instead result in a persistence exception, depending on the entity state and provider behavior.

Key points

Interview questions

What happens if you change a managed entity after calling `persist()`?

The entity remains managed by the persistence context. Its state changes are tracked by the JPA provider, so another `persist()` call is normally unnecessary. During flush, the provider synchronizes the entity's current state with the database. This behavior is commonly called dirty checking.

How is `persist()` different from `merge()`?

`persist()` is used to make a new entity instance managed. `merge()` instead copies state from the supplied entity into a managed instance and returns that managed instance. The object passed to `merge()` should not be assumed to become managed. This distinction matters when working with detached entities.

What does `EntityManager.persist()` do?

`persist()` takes a new entity instance and makes it managed by the current persistence context. The provider then treats that entity as something that should be inserted into the database. The SQL operation can be delayed until the persistence context is flushed. After the entity is managed, changes to it can be detected automatically.

Does `persist()` immediately insert the row into the database?

Not necessarily. `persist()` registers the entity with the persistence context and schedules it for insertion. The provider can delay the actual SQL until a flush occurs, which may happen explicitly or automatically. Therefore, `persist()` and SQL execution should be treated as separate steps.

Why is the persistence context important when explaining `persist()`?

The persistence context is the set of entity instances that the JPA `EntityManager` currently manages. Calling `persist()` places the entity into that managed set and lets the provider track its state. Database synchronization is then handled through the persistence context's flush process rather than requiring SQL for every object operation. This separation enables features such as automatic dirty checking and deferred database writes.