-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When Include.NON_DEFAULT
setting is used, isEmpty()
method is not called on the serializer
#4464
Comments
Could you provide simple reproduction, with Mapper configuration, class declarations and such? I tried writing a reproduction as below, but it seems to behave differently than the decription above. public static class Foo {
public String getFoo() {
return "";
}
}
@Test
public void test86() throws IOException {
ObjectMapper mapper = JsonMapper.builder()
.serializationInclusion(JsonInclude.Include.NON_DEFAULT)
.build();
String json = mapper.writeValueAsString(new Foo());
assertEquals("{}", json);
}
``` |
I probably did not make myself clear, but my case is about a custom serializer overriding the isEmpty method, which does not get called when NON_DEFAULT is used. It gets called only when NON_EMPTY is used, although documentation says NON_DEFAULT also excludes empty values. I attached a small Maven project demonstrating the issue. It works if we uncomment the NON_EMPTY annotation in Foo.java at line 9. |
|
Thank you for pointing out. I sort of drifted to a wrong point. You are right that |
Thank you for confirming, but is this a bug or it was meant to work this way and documentation is faulty or incomplete? |
Bug most likely. |
Here is the missing reproduction public class Test4464Test {
public static class BarSerializer extends StdScalarSerializer<Bar> {
public BarSerializer() {
super((Class<Bar>) null);
}
@Override
public void serialize(Bar value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeObject(value);
}
@Override
public boolean isEmpty(SerializerProvider provider, Bar value) {
return Bar.I_AM_EMPTY.equals(value.getName());
}
}
public static class Bar {
public static final String I_AM_EMPTY = "I_AM_EMPTY";
public String getName() {
return I_AM_EMPTY;
}
}
public static class Foo {
//@JsonInclude(Include.NON_EMPTY)
@JsonSerialize(using = BarSerializer.class)
public Bar getBar() {
return new Bar();
}
}
@Test
public void test86() throws IOException {
ObjectMapper mapper = JsonMapper.builder().serializationInclusion(JsonInclude.Include.NON_DEFAULT).build();
String json = mapper.writeValueAsString(new Foo());
assertEquals("{}", json);
}
} |
Include.NON_DEFAULT
setting is used, isEmpty()
method is not called on the serializer
Thank you @JooHyukKim -- merged for inclusion in 2.18.0. |
@JooHyukKim @cowtowncoder this seems likely to have led to #4741 - is there any chance that this change could be made configurable so that users can get the old behaviour if they prefer it? |
Thank you for investigating, @pjfanning! Awkward situation here, the intention was to get behavior sync with what the documentation says it would. Considering it being a regression? Yes, I think we could offer the old behavior configurable (SemVer..) A bit worried about maintainability tho, I hope who issued #4741 could take your suggestion of using Always. Considering the change was to actually get the right behavior --again as per documentation -- we might need some thinking on Jackson 3 tho. |
I am bit skeptical of technical feasibility of configurability option. At the same, regression is unfortunate. As to semantics, I am not sure why the claim wrt "isEmpty()" was made in documents: to me, DEFAULT really means either:
So no, Given all of these, I wonder if we should actually revert change wrt this issue. EDIT: Actually re-reading Annotation Javadocs for |
If we get intended and right behavior back on production? Yes. I'd like to suggest we get the correct behavior working, then provide workaround for use cases expecting different(unintended) behavior. Because it seems like the documentation is being interpreted in different perspective. |
@JooHyukKim I was bit too hasty there; I don't think we need to revert behavior, fortunately. Thank you and @pjfanning for help here. |
Search before asking
Describe the bug
Documentation says that when Include.NON_DEFAULT is used, null, empty and default values of a property are skipped on serialization. It is not clear how the empty check is done because the isEmpty method of the serializer is called only when Include.NON_EMPTY is used explicitly.
I have a case where I set Include.NON_DEFAULT globally on the ObjectMapper, and I have implemented a custom serializer to override the isEmpty method and thus let Jackson know when my object is empty. But my custom implementation of the isEmpty method is not called.
The only way to have it called by Jackson is to explicitly override the property inclusion configuration and use NON_EMPTY instead of the global NON_DEFAULT.
Version Information
2.15.3
Reproduction
<-- Any of the following
-->
// Your code here
Expected behavior
No response
Additional context
No response
The text was updated successfully, but these errors were encountered: