Skip to content

Deserialize null, when java type is "TypeRef of TypeRef of T", does not provide "Type(Type(null))" #2303

@mcoolive

Description

@mcoolive

Dependency

jackson = '2.9.7'
compile "com.fasterxml.jackson.core:jackson-databind:$jackson"

Short explanation

In Kotlin, I got an issue when I deserialize the value in the context of a reference type that include another reference type. I provide here a reproduction scenario in Java based on AtomicReference (I don't think there is a real use-case that use an AR of AR of Integer, but with a kind of DSL, it may happen to have a similar inclusion...)

So, when we deserialize an 22, we get an AR of AR of 22 as expected. But when we deserialize the null value, we get an AR of null (instead of AR of AR of null).

I think there is 2 issues:

(1) the getNull method of AtomicReference always returns "new AtomicReference()". I think it should be smarter and use contextual information such fullType or simply call _valueDeserializer.getNull() -- but _valueDeserializer was null during my tests because of (2).

(2) the bean propertyCreator has distinct deserializer and nullProvider. In the case of ReferenceTypeDeserializer, a new contextual deserializer is created, which is able to deserialize its content. Then the deserializer of the bean propertyCreator is updated, but not its nullProvider

To reproduce

class MyBean {
    private AtomicReference<AtomicReference<Integer>> refRef;
    public AtomicReference<AtomicReference<Integer>> getRefRef() {
        return refRef;
    }
    public void setRefRef(AtomicReference<AtomicReference<Integer>> refRef) {
        this.refRef = refRef;
    }
}

@Test
void myTest() throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    ObjectReader objectReader = objectMapper.readerFor(MyBean.class);

    MyBean intRef = objectReader.readValue(" {\"refRef\": 2 } ");
    Assertions.assertNotNull(intRef.refRef); // succeeds
    Assertions.assertNotNull(intRef.refRef.get()); // succeeds
    Assertions.assertEquals(intRef.refRef.get().get(), new Integer(2)); // succeeds

    MyBean nullRef = objectReader.readValue(" {\"refRef\": null } ");
    Assertions.assertNotNull(intRef.refRef); // succeeds
    Assertions.assertNotNull(intRef.refRef.get()); // fails
    Assertions.assertNull(intRef.refRef.get().get()); // fails
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions