Card 04/ 06
Spring Data save(): Updating an Existing Row Instead of Inserting
Called on an entity that already has an id, save changes that row and adds nothing.
save() in a Spring Data repository does not always insert. It checks whether the entity, the object mapped to a table row, is new, which for most entities means whether its id is still empty. A new entity is inserted; an entity that already has an id is merged into the existing row, which updates it.
"Empty" depends on the id's type: null for an object type such as Long, and 0 for a primitive long. An entity with a @Version field is judged by the version instead. save() also returns the saved entity, and after a merge that is a different object from the one you passed in, so keep working with the returned value.
Loading a ride, changing its status and saving it:
RideEntity existing = repo.findById(id).orElseThrow();
existing.status = "completed";
repo.save(existing);save() on existing id: count before=3 after=3 (same id updated, not inserted)The table still has three rows. The name reads as though it always creates something new, and code written on that assumption goes wrong: loading a ride, changing one field and saving it, in order to make a copy, overwrites the original instead.
The same rule is what makes "load, modify, save" the normal way to change a row, and it is why Spring Data has no separate update() method. To create a copy, build a new entity with no id and save that.
← → move through sections and cards