Skip to content
This repository has been archived by the owner on Jan 22, 2019. It is now read-only.

Issue with List<Optional> when Optional.absent() exists in the list #37

Closed
JYang-Addepar opened this issue Jan 23, 2014 · 1 comment
Closed
Milestone

Comments

@JYang-Addepar
Copy link

Hi,

Not sure if this has been reported before. 'null' insideList<Optional> failed to deserialize to Optional.absent(). This problem exists in the latest 2.3.1 code.

As a side node,List<List<String>>works, so I assume it's not about generics or String not being able to deserialize null. It also works when Optional is inside the object with List<JacksonObject>.

Below test case failed due to inconsistency of List<Optional> deserialization.

  @Test
  public void testOptionalCollection() throws Exception {
    ObjectMapper mapper = new ObjectMapper().registerModule(new GuavaModule());

    TypeReference<List<Optional<String>>> typeReference =
        new TypeReference<List<Optional<String>>>() {};

    List<Optional<String>> list = new ArrayList<>();
    list.add(Optional.of("2014-1-22"));
    list.add(Optional.<String>absent());
    list.add(Optional.of("2014-1-23"));

    String str = mapper.writeValueAsString(list);
    assertEquals("[\"2014-1-22\",null,\"2014-1-23\"]", str);

    List<Optional<String>> serializedList = mapper.readValue(str, typeReference);
    assertEquals(list, serializedList);
  }

This following test case works.

@Test
  public void testObjectWithOptionalCollection() throws Exception {
    ObjectMapper mapper = new ObjectMapper().registerModule(new GuavaModule());
    List<OptionalInJackson> listOptional = new ArrayList<>();

    OptionalInJackson optionalJackson = new OptionalInJackson();
    optionalJackson.setStr(Optional.of("THE WORST"));
    listOptional.add(optionalJackson);

    OptionalInJackson empty = new OptionalInJackson();
    empty.setStr(Optional.<String>absent());
    listOptional.add(empty);

    String str = mapper.writeValueAsString(listOptional);

    assertEquals("[{\"str\":\"THE WORST\"},{\"str\":null}]", str);

    List<OptionalInJackson> fine = mapper.readValue(str, new TypeReference<List<OptionalInJackson>>() {});
    assertEquals(listOptional, fine);

  }

 static class OptionalInJackson {
    @JsonProperty("str")
    private Optional<String> str;

    OptionalInJackson(){
      str = Optional.absent();
    }

    public void setStr(Optional<String> opt) {
      str = opt;
    }

    public Optional<String> getStr() {
      return str;
    }

    @Override
    public boolean equals(Object other) {
      if (other == null) return false;
      return StringUtils.equals(toString(), other.toString());
    }

    @Override
    public String toString() {
      return str.toString();
    }
  }
@cowtowncoder
Copy link
Member

Turns out this is due to FasterXML/jackson-databind#407 which was fixed for 2.4.0-SNAPSHOT, but not backported in 2.3. I went ahead and backported relevant fix, so this will work with 2.3.3.

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

No branches or pull requests

2 participants