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

DeserializationProblemHandler is not working with wrapper type when returning null #3450

Closed
LJeanneau opened this issue Apr 8, 2022 · 6 comments
Labels
has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue
Milestone

Comments

@LJeanneau
Copy link

Describe the bug
Overriding handleWeirdStringValue method of DeserializationProblemHandler and returning null as a default value for a wrapper type (Integer in my case) is not working and is changed to 0 during deserialization
It seems to me that this is due to _parseInteger method using _parseIntPrimitive in StdDeserializer and I can't figure out a way to workaround this behavior. Trying to use an optional leads to Optional.of(0) being returned.

Version information
Bug has been observed in 2.13.2.2 ; was previously working with 2.10.2

To Reproduce

public class LenientDeserializationProblemHandler extends DeserializationProblemHandler {

    @Override
    public Object handleWeirdStringValue(DeserializationContext ctxt, Class<?> targetType, String valueToConvert,
        String failureMsg) throws IOException {

        // I just want to ignore badly formatted value
        return null;
    }
}

public class TestPojo {

    private Integer myInteger;

    public Integer getMyInteger() {
        return myInteger;
    }

    public void setMyInteger(Integer value) {
        myInteger = value;
    }
}

public class DeserializationProblemHandlerTest {

    private final ObjectMapper mapper =
        JsonMapper.builder().addHandler(new LenientDeserializationProblemHandler()).build();

    @Test
    public void present_value_is_working() throws JsonProcessingException {
        TestPojo pojo = mapper.readValue("{\"myInteger\" : \"12\"}", TestPojo.class);

        assertEquals(12, pojo.getMyInteger());
    }

    @Test
    public void non_present_value_is_working() throws JsonProcessingException {
        TestPojo pojo = mapper.readValue("{\"myInteger\" : \"\"}", TestPojo.class);

        assertNull(pojo.getMyInteger());
    }

    @Test
    public void badly_formatted_value_is_not_working() throws JsonProcessingException {
        TestPojo pojo = mapper.readValue("{\"myInteger\" : \"obviously not an integer\"}", TestPojo.class);

        // This test is failing with jackson-databind 2.13.2.2 but worked on 2.10.2
        assertNull(pojo.getMyInteger());
    }
}

Expected behavior
Expected behavior is deserializing null instead of 0 as requested by DeserializationProblemHandler as null is a valid value for Integer

@LJeanneau LJeanneau added the to-evaluate Issue that has been received but not yet evaluated label Apr 8, 2022
@cowtowncoder cowtowncoder added 2.13 has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue and removed to-evaluate Issue that has been received but not yet evaluated labels Apr 8, 2022
@cowtowncoder
Copy link
Member

Thank you for reporting this issue. I cannot say off-hand whether null should be acceptable value: to me it does not seem like it would be for primitive values. But the exception should clearly indicate if this is the reason.

Thank you for including unit tests.

@LJeanneau
Copy link
Author

LJeanneau commented Apr 11, 2022

I have finally found a workaround by doing the following in my model

public class TestPojo {

    private Integer myInteger;

    public Integer getMyInteger() {
        return myInteger;
    }

    public void setMyInteger(Number value) {
        myInteger = (Integer) value;
    }
}

Changing the setter parameter to a Number indicates to Jackson to use the NumberDeserializer instead of the IntegerDeserializer. The NumberDeserializer returns the result of the method handleWeirdStringValue without altering it which solves my issue.
It seems pretty strange that NumberDeserializer and IntegerDeserialiser are inconsistent in their behavior regarding null handling

@cowtowncoder
Copy link
Member

Ok, yes, this is a bug @LJeanneau -- caused by calling "primitive" handler where it really isn't one.
I'll see how this can be fixed.

@cowtowncoder
Copy link
Member

Fixed for 2.14.0 -- theoretically could also backport into 2.13(.3).

cowtowncoder added a commit that referenced this issue Apr 21, 2022
@cowtowncoder cowtowncoder added 2.13 and removed 2.14 labels Apr 21, 2022
@cowtowncoder cowtowncoder added this to the 2.13.3 milestone Apr 21, 2022
@cowtowncoder
Copy link
Member

Backport in 2.13 branch for 2.13.3 release.

@LJeanneau
Copy link
Author

Thanks for the fix ; tested with success on my scenario in 2.13.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue
Projects
None yet
Development

No branches or pull requests

2 participants