Skip to content
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

Include.NON_DEFAULT doesn't work for value types, 2.7.0 and up #1663

Closed
shawjef3 opened this issue Jun 15, 2017 · 10 comments
Closed

Include.NON_DEFAULT doesn't work for value types, 2.7.0 and up #1663

shawjef3 opened this issue Jun 15, 2017 · 10 comments

Comments

@shawjef3
Copy link

Please see the project at https://github.com/shawjef3/jackson-default-bug. It has a single test, which fails for Jackson 2.7.0 and higher, but succeeds for lower versions.

int i = 1;

@JsonProperty("i")
@JsonInclude(JsonInclude.Include.NON_DEFAULT) //doesn't work for jackson 2.7.0 and up
public int getI() {
    return i;
}

In the above an ObjectMapper will include "i" in the resulting json if i is 1, but not if i is 0. This behavior is reversed for versions below 2.7.0. I believe if the default is 1, as in the above code, it should not be included when the actual value is 1.

@shawjef3
Copy link
Author

Oddly, Jackson >= 2.7.0 does behave properly if @JsonInclude(JsonInclude.Include.NON_DEFAULT) is at the class level, rather than the property level.

@cowtowncoder
Copy link
Member

@shawjef3 This may be matter of documentation. NON_DEFAULT has slightly different semantic if applied as default setting for types, properties vs on class.

Specifically: if applied to a field (or as global default), it will only prune type-default: so for int, value 0. If you want to filter out default values property has for enclosing POJO, annotation must be on class.
Semantic difference is unfortunate, but the way system works this was the only stable set up.

So: if applied to property, default value to filter is whatever default type has: if to enclosing POJO class, value that property has for that POJO's default instance (one constructed with zero-arg constructor).

@shawjef3
Copy link
Author

shawjef3 commented Jun 16, 2017

@cowtowncoder Thanks, I see the difference. Are you sure it's supposed to be that way vs. the old way? I don't see anything in the 2.7.0 changelog about it, yet it changed with version 2.7.0.

The reason I'm bringing this up as a bug, is that I upgraded some code from 2.4 to the latest version, and the change in how defaults are serialized broke some tests.

@peteriman
Copy link

peteriman commented Jun 23, 2017

Hi @cowtowncoder,

I tried using @JsonInclude(Include.NON_DEFAULT) on a property Date but it doesn't work.
I'm using 2.8.9.

https://fasterxml.github.io/jackson-annotations/javadoc/2.8/com/fasterxml/jackson/annotation/JsonInclude.Include.html#NON_DEFAULT

When NOT used for a POJO (that is, as a global default, or as property override), definition is such that:

  • All values considered "empty" (as per NON_EMPTY) are excluded
  • Primitive/wrapper default values are excluded
  • Date/time values that have timestamp (long value of milliseconds since epoch, see Date) of 0L are excluded

It still serializes the Date as 0 instead of excluding it. I have included my code below.

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Date;

public class NewClass {

    public static void main(String[] args) throws Exception {
        
        ObjectMapper objectMapper = new ObjectMapper();
        
        DTO dto1 = new DTO();
        System.out.println(objectMapper.writeValueAsString(dto1));
        // prints out {"date":0} when it should print out {}
        
    }

}

class DTO {

    @JsonInclude(Include.NON_DEFAULT)
    private Date date = new Date(0);

    public DTO() {
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

}

@cowtowncoder
Copy link
Member

cowtowncoder commented Jun 23, 2017

@shawjef3 Part of the problem here is that some changes may have been regressions; and in other cases clarifications to rules may not have explicitly matching issues filed. But the big thing that was documented on https://github.com/FasterXML/jackson/wiki/Jackson-Release-2.7 was #952 (Revert back expansion of NON_EMPTY handling), and some changes may stem from that one.
2.7 was and is planned to be the baseline where definition is (...more) solid, and hope is that no planned changes would be needed. However, with 2.8 addition of "config overrides" (ability to specify full global and per-type inclusion defaults), interpretation of NON_DEFAULT had to be carefully weighed -- earlier only per-property/per-class settings existed.

@cowtowncoder
Copy link
Member

@uberstud87 Could you please file a separate issue for this: while these things appear possibly related, I think there is specific thing about Date (and Calendar) values here that only applies to those types.
It goes back to definition of "what is empty" (NON_EMPTY), and before 2.7 (... and possibly in some modules still, Joda time?) timestamp value of 0 was considered empty. But users did not think this was intuitive, and 2.7 clarified that these are indeed not "empty" but "default".
To reflect these changes, serializers need(ed) to be changed, and this is where specific handling for types may vary from general behavior.

@peteriman
Copy link

peteriman commented Jun 24, 2017

@cowtowncoder I have filed a separate issue #1676 as you advised.

@akanssha1
Copy link

@cowtowncoder , which version has the fix of using non_empty property with integer such that 0 isn't omitted out from the output?

@cowtowncoder
Copy link
Member

@akanssha1 I do not remember off-hand for sure, but 2.9 and 2.10 certainly. My guess is that'd be in 2.8.0 as well.

@cowtowncoder
Copy link
Member

Since behavior change is now pretty old, new behavior is considered the default; closing this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants