Skip to content
This repository was archived by the owner on Jan 20, 2025. It is now read-only.
This repository was archived by the owner on Jan 20, 2025. It is now read-only.

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

@JYang-Addepar

Description

@JYang-Addepar

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();
    }
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions