-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Describe the bug
When setting a custom deserializer for a property using BeanDeserializerBuilder.addOrReplaceProperty that customer deserializer is not applied when the POJO has a constructor method.
After some debugging, it has to do with the _propertyBasedCreator field in the BaseBeanDeserializer class. If the POJO has a constructor method that the _propertyBaseCreator field is set. But the properties stored in those fields are not in sync with the _beanProperties fields which has the value deserializer applied from the addOrReplaceProperty.
Currently I'm using version 2.13 and running into this issue when using this library
https://github.com/codesqueak/jackson-json-crypto.
That library above add an annotation and if string fields are annotated with that annotation it will serialize the string into an encrypted format.
Version information
2.13
To Reproduce
If I have two classes
class A {
private String value = null
public A(String value) ...
@JsonProperty
@Encrypt
public getValue() ...
public setValue(String: value) ...
}
class B {
private String value = null
public B() ...
@JsonProperty
@Encrypt
public getValue() ...
public setValue(String: value) ...
}
And have a BeanDeserializationModifier that looks like this from the gitbug project above
public class EncryptedDeserializerModifier extends BeanDeserializerModifier {
private final EncryptionService encryptionService;
public EncryptedDeserializerModifier(final EncryptionService encryptionService) {
this.encryptionService = encryptionService;
}
@Override
public BeanDeserializerBuilder updateBuilder(final DeserializationConfig config, final BeanDescription beanDescription, final BeanDeserializerBuilder builder) {
var it = builder.getProperties();
while (it.hasNext()) {
var property = it.next();
if (null != property.getAnnotation(Encrypt.class)) {
var current = property.getValueDeserializer();
builder.addOrReplaceProperty(property.withValueDeserializer(new EncryptedJsonDeserializer(encryptionService, current)), true);
}
}
return builder;
}
}
I can properly serialize and then deserialize class B but not class A.
// Does not work
var objectA = new A("Some String")
var jsonA = objectMapper.writeValue(objectA)
var readA = objectMapper.readValue(jsonA, A.class)
// Does work
var objectB = new B("Some String")
var jsonB = objectMapper.writeValue(objectB)
var readB = objectMapper.readValue(jsonB, B.class)
Expected behavior
Both approaches should be able to properly read in a JSON value using a customer deserializer.
Additional context
Add any other context about the problem here.