Concurrent edit conflicts
Status: ✅ Implemented
Intent
Section titled “Intent”Two users open the same record; both edit; both save. Without protection the second save silently erases the first — the classic lost update. Enterprise apps need the second writer to know, and to choose: see the other changes, or overwrite them deliberately.
Solution
Section titled “Solution”Add a @Version field (an int or long) to the entity:
public class Article implements Identifiable { String id; String name; @Version @Hidden long version; // @Hidden keeps it off the form; it still travels in state}- Every successful save bumps the version automatically.
- A save carrying a version older than the stored one (someone else saved in between) is
rejected: nothing is persisted and the user gets the conflict dialog — “Modificado por
otro usuario” — with two choices:
- Recargar — discard my changes and reload the record with theirs.
- Sobrescribir — my version wins, explicitly. The save is re-dispatched with
_forceOverwrite; the version keeps moving forward (the stale number is never resurrected).
- Works out of the box on
AutoCrudeditors and inline row editing (@InlineEditing), where the dialog re-sends the same edited row on overwrite. - Entities without a
@Versionfield are untouched — the feature is fully opt-in.
Database-backed repositories
Section titled “Database-backed repositories”The check compares against store().findById(...) at save time. A store-managed version — a
field annotated with JPA’s @jakarta.persistence.Version (or Spring Data’s
@org.springframework.data.annotation.Version) — takes part in that check like Mateu’s own
@Version, so a stale save gets the same dialog and Sobrescribir adopts the stored version; but
Mateu does not bump it, because the persistence provider increments it itself. For a race the
check cannot see, throw OptimisticLock.StaleEditException from save (e.g. translate Spring’s
OptimisticLockingFailureException in your store).
Related
Section titled “Related”- Autosave — fewer stale windows by saving continuously
- Audit history —
Auditablerecords who changed what