jackson-modules-java8 icon indicating copy to clipboard operation
jackson-modules-java8 copied to clipboard

@JsonCreator change the behaviour of Optional<>

Open patryk-beekeeper opened this issue 3 years ago • 1 comments

Describe the bug I have a use case when lack of field in json has different meaning than setting this field to null. To model this I use Optional<>. It works fine without @JsonCreator, but do not work with @JsonCreator

Version information 2.12.4

To Reproduce

class WithoutJsonCreator {
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public Optional<String> test;
}

class WithJsonCreator {
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public Optional<String> test;

    @JsonCreator
    public WithJsonCreator(@JsonProperty("test") Optional<String> test) {
        this.test = test;
    }
}

  @Test
  void shouldWorkWithAndWithoutJsonCreator() throws JsonProcessingException {
      String json = "[{},{\"test\":null}]";
      ObjectMapper objectMapper = new ObjectMapper().registerModule(new Jdk8Module());
      List<WithoutJsonCreator> without =  objectMapper.readValue(json, new TypeReference<>() {});

      assertNull(without.get(0).test);
      assertEquals(Optional.empty(), without.get(1).test);
      assertEquals(json, mapper.writeValueAsString(without));

      List<WithJsonCreator> with =  objectMapper.readValue(json, new TypeReference<>() {});

      System.out.println(with.get(0).test); // Optional.empty
      System.out.println(with.get(1).test); // Optional.empty
      assertEquals(json, mapper.writeValueAsString(with)); // FAIL: expected: <[{},{"test":null}]> but was: <[{"test":null},{"test":null}]>
  }

Expected behavior The behaviour for both classes should be the same and test should pass.

patryk-beekeeper avatar Jan 05 '22 10:01 patryk-beekeeper

Since Optional handling provided by Java 8 module, transferring there.

cowtowncoder avatar Jan 05 '22 17:01 cowtowncoder

This is a limitation -- only Creator-passed values can detect absence of value; for fields and setters nothing is done if no input is found. So the behavior is different but that is not considered a bug nor can be easily fixed. There may be an issue for jackson-databind to support handling of "absent" values for Fields and Methods (there is one for enforcing "required"-ness, and if that was done, "absent" aspect could also be supported.

Closing here, however, since this is not really specific to Optional nor can be solved here.

cowtowncoder avatar Sep 24 '22 00:09 cowtowncoder