-
Notifications
You must be signed in to change notification settings - Fork 21
Invalidating SerializationInclusion.NON_NULL of other modules #52
Comments
Unit test much appreciated. Usually problems like this are due to optimized handling which may not take into account all processing logic that is being added. The reason why pre-registration may work is if serializer is constructed first before afterburner has a chance to add optimized handler. |
Hmmh. Actually, it might not be that easy to see what is going on, as this appear to involve additional serializers from linked-to project. It would be good to have a stand-alone unit test that exhibits the problem only using classes declared in test class itself, to isolate the problem. The challenge is that Afterburner does not change inclusion settings; and the code does check for inclusion. But obviously something does go wrong with optional type handling, somehow. Isolating that difference would be necessary since I can not add dependency from afterburner test to the other project. |
The serializer is a bit silly but does the job :). public class SampleObject {
private String field1;
private Integer field2;
private Integer field3;
public SampleObject(String field1, Integer field2, Integer field3) {
this.field1 = field1;
this.field2 = field2;
this.field3 = field3;
}
// getter setters
}
public class NullSerializerTest {
@Test
public void test() throws JsonProcessingException {
SampleObject sampleObject = new SampleObject(null, 2, 3);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new AfterburnerModule());
SimpleModule simpleModule = new SimpleModule();
simpleModule.setSerializerModifier(new Only2BeanSerializerModifier());
objectMapper.registerModule(simpleModule);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
String json = objectMapper.writeValueAsString(sampleObject);
assertEquals("{\"field2\":2}", json);
}
public class Only2BeanSerializerModifier extends BeanSerializerModifier {
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
return beanProperties.stream().map((w) -> {
BeanPropertyWriter mapping = w;
if (Integer.class.isAssignableFrom(w.getPropertyType())) {
mapping = new Only2BeanPropertyWriter(w);
}
return mapping;
}).collect(Collectors.toList());
}
}
public class Only2BeanPropertyWriter extends BeanPropertyWriter {
protected Only2BeanPropertyWriter(BeanPropertyWriter base) {
super(base);
}
@Override
public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider prov) throws Exception {
Object val = get(bean);
if((val == null || !val.equals(2)) && _nullSerializer == null) {
return;
}
super.serializeAsField(bean, jgen, prov);
}
}
}
|
Oh wait, it failed without AfterBurner as well. Hmm.. |
OK, fixed it. Probably can be simplified though. It looks like it ignores the BeanPropertyWriter when AfterBurner is registered even though BeanSerializerModifier returns it (according to my debug steps). |
Thanks -- that sounds plausible, yes. Need to see what checks need to be added to avoid optimizing this case. |
Accidentally closed the wrong issue. |
Ah. Just realized that a more likely explanation is the ordering of modules. If so, not sure if this actually can be solved or not. |
Turned out there is another way to solve this problem, by blocking use of optimized |
👍, thanks. |
zapodot/jackson-databind-java-optional#2
tl;dr
If a different module with custom SerializationInclusion handling is registered after AfterBurnerModule, nulls are de/serialized still as nulls, ignoring the other module. The workaround is to
Unit tests are available in the issue above.
The text was updated successfully, but these errors were encountered: