spring-data-rest
spring-data-rest copied to clipboard
Custom Serializers cannot apply patch method [DATAREST-1566]
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
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.