Hibernate save vs persist vs saveOrUpdate
Fast recall
Quick revision
Core answer
Whether you know the JPA-standard API versus Hibernate's proprietary methods and which to use in modern apps
Calling Hibernate Session methods directly instead of EntityManager or Spring Data JPA repositories, and calling persist on a detached entity
Explain that Spring Data's save() uses SimpleJpaRepository, calling persist() or merge() based on entity state
Interview-ready guide
Interview answer
In new JPA code, call persist when the object is new. For detached input, merge returns the managed copy; continue with the returned object rather than assuming the original became managed. Old Hibernate tutorials often compare save, update, and saveOrUpdate, but those native methods no longer form the recommended API in Hibernate 6. Spring Data's save method is a separate abstraction and decides between EntityManager.persist and EntityManager.merge.
For example, persist is the normal JPA operation for a new Customer. For a detached Customer, merge returns the managed copy, so I keep and use the returned reference. Hibernate's older save and saveOrUpdate methods are provider APIs and are deprecated in current Hibernate versions.
Hibernate save vs persist vs saveOrUpdate
Direct Answer
EntityManager.persist is the standard JPA operation for making a new entity managed. Hibernate's Session.save, update, and saveOrUpdate are older native APIs and are deprecated in modern Hibernate; new code normally uses persist for new entities and merge for detached state. Spring Data repository.save chooses persist or merge from its new-entity detection.
Code Example
import jakarta.persistence.*;
// JPA standard: persist() inserts a transient entity, returns void
@PersistenceContext EntityManager em;
void createWithJpa(Order order) {
em.persist(order); // order must have NO id yet
}
// Hibernate native: save() returns the generated id immediately
// Long id = (Long) session.save(order);
// Modern Spring Data JPA: one method handles insert AND update
interface OrderRepository extends JpaRepository<Order, Long> {}
class OrderService {
private final OrderRepository repo;
OrderService(OrderRepository repo) { this.repo = repo; }
Order saveOrder(Order order) {
// null id -> SimpleJpaRepository calls persist() (INSERT)
// set id -> it calls merge() (SELECT then INSERT/UPDATE)
return repo.save(order);
}
}
Common Mistakes & Pitfalls
- Using Hibernate Session instead of EntityManager — calling
session.save()in Spring services ties code to Hibernate; prefer repositories or EntityManager. - Calling persist() on a detached entity —
persist()only works on transient entities and throws otherwise; usemerge()orrepository.save(). - Assuming save() always INSERTs — with a non-null ID, Spring Data calls
merge(), which does a SELECT first; if it's truly new, keep the ID null to avoid the extra query.
Check your understanding
Answer these without looking back at the article.
- How does Spring Data's save() know whether to insert or update?
- What is the difference between save() and saveAndFlush() in Spring Data?
- What happens if you persist() an entity that already has an ID?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.