Skip to content

Fix for @version field value ignored when updating data. - #2603

Open
ruthst00 wants to merge 1 commit into
spring-projects:mainfrom
ruthst00:DATAREST-1329-ruthes00
Open

Fix for @version field value ignored when updating data.#2603
ruthst00 wants to merge 1 commit into
spring-projects:mainfrom
ruthst00:DATAREST-1329-ruthes00

Conversation

@ruthst00

@ruthst00 ruthst00 commented Sep 10, 2026

Copy link
Copy Markdown

Fixes #1689

Root Cause

In DomainObjectReader.doMerge() (used for HTTP PATCH / JSON Merge Patch), the version field sent by the client was being silently stripped from the JSON node before Jackson applied it to the target object. This happened because MappedJacksonProperties.isWritableField() returns false for version properties, and doMerge() removes any non-writable field from the JSON node:

if (!mappedProperties.isWritableField(fieldName)) {
    i.remove();  // ← version field was removed here
    continue;
}

As a result, the existing version from the database was always kept, so the underlying store's optimistic locking mechanism never saw a version mismatch — even when the client sent a wrong version number.

Fix

DomainObjectReader.doMerge() — Instead of unconditionally removing all non-writable fields, the fix checks if the non-writable field is the version property. If it is, the field is kept in the JSON node so Jackson can apply it to the target object, enabling the store's optimistic locking to detect mismatches. The id field is still stripped to prevent clients from changing resource identity.

if (!mappedProperties.isWritableField(fieldName)) {
    // Allow the version field to pass through so that the underlying store's optimistic locking
    // mechanism can detect version mismatches (GH-1689). The id field is still stripped to
    // prevent clients from changing the identity of the resource.
    PersistentProperty<?> nonWritable = mappedProperties.getPersistentProperty(fieldName);
    if (nonWritable == null || !nonWritable.isVersionProperty()) {
        i.remove();
    }
    continue;
}

Behavior preserved

  • HTTP PUT: retainIdentifierAndVersion() still overwrites the client's version with the server's version before deserialization, so PUT cannot mutate the version (existing tests doesNotWipeIdAndVersionPropertyForPut and doesNotAllowMutatingIdAndVersionViaPutBody still pass).
  • JSON Patch: JsonPointerMapping.forWrite() still rejects writes to the version property via JSON Patch operations (existing test forWriteRejectsVersionProperty still passes).
  • HTTP PATCH (JSON Merge Patch): The client-provided version is now applied to the object, allowing the store to throw OptimisticLockException on version mismatch.

Tests added

Two new tests in DomainObjectReaderUnitTests:

  • appliesVersionFromClientForPatch() — verifies the version from the client is applied during PATCH
  • doesNotAllowMutatingVersionViaPutBody() — verifies the version cannot be changed via PUT

  • You have read the Spring Data contribution guidelines.
  • You use the code formatters provided here and have them applied to your changes. Don’t submit any formatting related changes.
  • You submit test cases (unit or integration tests) that back your changes.
  • You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).

…ating data.

Signed-off-by: ruthes00 <ruthes00@gmail.com>
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 10, 2026
@ruthst00 ruthst00 changed the title DATAREST-1329-ruthes00: Fix for @version field value ignored when updating data. Fix for @version field value ignored when updating data. Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@version field value ignored when updating data [DATAREST-1329]

2 participants