spring-projects / spring-data-rest

Simplifies building hypermedia-driven REST web services on top of Spring Data repositories
https://spring.io/projects/spring-data-rest
Apache License 2.0
914 stars 560 forks source link

Custom Serializers cannot apply patch method [DATAREST-1566] #1928

Open spring-projects-issues opened 3 years ago

spring-projects-issues commented 3 years ago

huisezhiwei opened DATAREST-1566 and commented

I have a Dictionary entity bean contain fields like "dictCode" and "dictValue". then define a DTO class contain fields like "code" and "value" . finally register a customer Module to serializer

 

public class DictionaryMapper extends SimpleModule {
    @Override
    public void setupModule(SetupContext context) {
        SimpleSerializers serializer = new SimpleSerializers();
        serializer.addSerializer(Dictionary.class, new JsonSerializer<Dictionary>() {
            @Override
            public void serialize(Dictionary value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                gen.writeNumberField("id", value.getId());
                gen.writeStringField("code", value.getDictCode());
                gen.writeStringField("value", value.getDictValue());
            }
            @Override
            public boolean isUnwrappingSerializer() {
                return true;
            }
        });
        context.addSerializers(serializer);

        SimpleDeserializers deserializers = new SimpleDeserializers();
        deserializers.addDeserializer(Dictionary.class, new JsonDeserializer<Dictionary>() {
            @Override
            public Dictionary deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
                JsonNode node = p.getCodec().readTree(p);
                ObjectMapper op = new ObjectMapper();
                DictionaryResource resource = op.convertValue(node, DictionaryResource.class);
                return new Dictionary(resource);
            }
        });
        context.addDeserializers(deserializers);
    }
}

everything is ok in get post and put method , bug in patch method request . the JsonNode always return EmptyJson ("{}")

I try to debug and find the doMerge method on the DomainObjectReader will remove the DTO fields becasue  mappedProperties.isWritableProperty return false . 

 

 


No further details from DATAREST-1566

darioseidl commented 2 years ago

We're having the same problem with jackson-datatype-money and the MonetaryAmountDeserializer, after upgrading Spring Boot to 2.5.8.

The MonetaryAmountDeserializer deserializes "amount" and "currency" from JSON, but the MappedProperties only knows about number and currency, so mappedProperties.isWritableProperty(fieldName) returns false for "amount" and it is removed in DomainObjectReader.doMerge and never passed to the MonetaryAmountDeserializer.