Update or SaveorUpdate in CRUDRespository, Is there any options available
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
CrudRepository does not have separate update() or saveOrUpdate() methods like older Hibernate-focused APIs. In Spring Data, the normal entry point is save(), and what actually happens depends on the entity state, the identifier, and whether you are modifying a managed entity inside a transaction.
How save() Behaves
For CrudRepository, save() is the standard method for both inserts and updates.
If the entity is new, JPA persists it. If the entity already exists, Spring Data delegates to the persistence provider and the row is updated. That is the closest equivalent to a "save or update" operation in this abstraction.
Managed Entities and Dirty Checking
In many cases you do not need to call save() for every update if the entity is already managed in the current transaction. JPA dirty checking will detect field changes and flush them automatically at commit time.
This is still an update, even though save() is never called. Once the entity is managed by the persistence context, changing its state inside a transaction is enough.
That distinction matters because many developers coming from Hibernate's saveOrUpdate() think they must call a repository method after every field assignment. With JPA, that is often unnecessary.
When a Custom Update Query Is Better
Sometimes you do not want to load the entity first. Maybe you need to update one column on many rows, or you want to avoid fetching an object only to change a single value. In those cases, declare a custom modifying query.
This is the closest thing to an explicit repository-level update operation.
save() Versus Hibernate saveOrUpdate()
Older Hibernate APIs exposed methods such as saveOrUpdate() directly on the session. Spring Data intentionally presents a smaller abstraction surface. Instead of mirroring every Hibernate method, it gives you repository methods and lets the JPA provider handle persistence state under the hood.
That means the practical options are:
- '
save()for create or detached-entity update flows' - transactional dirty checking for managed entities
- '
@Modifyingqueries for direct database updates'
Those three patterns cover almost every common use case.
Common Pitfalls
One mistake is assuming save() always issues an SQL update immediately. It does not. Depending on the transaction and flush mode, the SQL may be delayed until flush or commit.
Another issue is updating detached entities without understanding what fields are populated. If you create a partially filled object with an existing identifier and call save(), you can accidentally overwrite columns with null values. Load the existing entity first unless you are sure the object is complete.
Developers also sometimes forget @Transactional on methods that rely on dirty checking. Without a proper transaction, the persistence context may not behave the way you expect.
Finally, custom update queries bypass normal entity state tracking. If the same entity is already loaded in the persistence context, its in-memory state can become stale unless you clear or refresh it.
Summary
- '
CrudRepositorydoes not provide separateupdate()orsaveOrUpdate()methods.' - Use
save()for standard create and update flows. - Let JPA dirty checking handle updates to managed entities inside a transaction.
- Use
@Modifyingqueries when you need direct SQL-style updates without loading the entity. - Be careful with detached entities and partial data, because
save()can overwrite existing values.

