Search code examples
jsonspringspring-data-restjson-patch

Spring JSON Patch unable to update nested Map object


in my application I'm trying to support JSON patch requests to apply partial update my entities and I'm using directly the implementation of Patch provided by Spring in the spring-data-rest library.

I'm not able to use the Spring Patch implementation to partially update Maps in Java, or the Spring implementation is not able to support such operation.

Spring Patch converts JSON patch operations to SPEL operations, and everything works fine with POJOs having fixed properties (or field), but it seems not working with Maps where I would assume the "fields" are the keys of the Map.

Knowing that behind the scenes Spring converts a JSON path to a SPEL operation, I've also tried to use a SPEL notation in my PATCH payload, without any result. This is what I've tried

Let's assume this is the situation:

//Here is my object
public class Book {

    public String author;

    public String ISBN;

    public Map<String, String> characters;


}

// Here I create a simple instance of the object
Book myBook = new Book();
myBook.author = "Me"
myBook.ISBN = "1234567890"
myBook.characters = new HashMap<>();
myBook.characters.put("protagonist", "Pinco");
myBook.characters.put("antagonist", "Pallo");
// Here the type of operations that work
[
    {"op": "replace", "path": "/author", "value": "NewAuthor"},
    {"op": "replace", "path": "/ISBN", "value": 0987654321 },
]

// I can also modify completely the Map if I want
[
    {"op": "replace", "path": "/characters", "value": {"protagonist": "Pallo", "antagonist": "Pinco"} }
]

// But I can't update a single value in the map
[
    {"op": "replace", "path": "/characters/protagonist", "value": "Pallo" },
    {"op": "replace", "path": "/characters/antagonist", "value": "Pinco" }
]

// I've also tried weird stuff, but doesn't work
[
    {"op": "replace", "path": "/characters[antagonist]", "value": "Pinco"}
]

I would expect the replace operation on the nested map to work by checking the key, but maybe I'm doing something wrong or I should simply represent all objects like POJOs with regular fields in order for this to work.


Solution

  • For all other that not already saw the corresponding issue and pull request for this, here it seems to be fixed, just verified it for our project (PATCHing a Map<Locale, String>) and it worked.

    Refer to: