OptimisticLockException 🔌 API

Optimistic lock conflict: OptimisticLockException / StaleObjectStateException / version mismatch

Someone else changed the record after you read it, so your update — based on an old version — was rejected to avoid overwriting their change.

Seen on: REST API

Meaning

Optimistic locking stores a version number or ETag with each record. An update must say which version it was based on; if the stored version has moved on, the write fails instead of silently losing the other change.

JPA/Hibernate throws OptimisticLockException or StaleObjectStateException (“Row was updated or deleted by another transaction”), Spring wraps it as ObjectOptimisticLockingFailureException, Mongoose throws VersionError, and REST APIs answer 409 Conflict or 412 Precondition Failed.

Common causes

  • Two users or workers edited the same record concurrently
  • Client kept an old copy and submitted it much later
  • Retry logic re-sent an update with a stale version
  • Background job updates the row while a user edits it

⚡ Quick fix

  1. Re-read the latest record, merge the user’s change, and retry with the new version
  2. Show users a “this record changed” message instead of overwriting
  3. Retry automatically only for idempotent, mergeable changes

Detailed fix by platform

Java

  1. java
    @Version private Long version;  // JPA entity
    
    try { repo.save(entity); }
    catch (ObjectOptimisticLockingFailureException e) { /* reload, merge, retry or tell the user */ }

Node.js

  1. javascript
    // Mongoose: VersionError — reload and re-apply
    const doc = await Model.findById(id); doc.set(changes); await doc.save();

REST API

  1. curl -X PUT https://api.example.com/v1/items/42 -H 'If-Match: "v7"' -d @item.json # send the current ETag/version

How to diagnose

  1. Versions — Requested vs current version/ETag
  2. Writers — Which other process updated the record?
  3. Retry — Does the client resend stale data?

🧠 Still stuck? Analyze your error

Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.