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

ObjectMapper.treeToValue() no longer invokes JsonDeserializer.getNullValue() #2972

Closed
andpal opened this issue Dec 5, 2020 · 2 comments
Closed
Milestone

Comments

@andpal
Copy link

andpal commented Dec 5, 2020

Describe the bug
If you invoke ObjectMapper::treeToValue it no longer uses JsonDeserializer::getNullValue on the class' declared deserializer when encountering a NullNode, instead just returning a plain null.

Version information
The regression began in 2.10.0, I think. I have tested 2.12.0 and the issue is present there. The last working release I have tested is 2.9.10.

To Reproduce
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>se.anpal</groupId>
    <artifactId>jackson-mve</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>

        <jackson.version>2.12.0</jackson.version>
        <!-- This is the last version where the test passes -->
        <!--<jackson.version>2.9.10</jackson.version>-->
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${jackson.version}</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.5.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M3</version>
            </plugin>
        </plugins>
    </build>
</project>

JsonElementTest.java

package se.anpal.jackson.mve;

import static org.junit.jupiter.api.Assertions.assertEquals;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.node.NullNode;

import org.junit.jupiter.api.Test;

import se.anpal.jackson.mve.JsonElementTest.JsonElement.JsonNull;

public class JsonElementTest {

    @Test
    public void test() throws Exception {
        NullNode input = NullNode.getInstance();
        JsonNull expected = JsonNull.INSTANCE;
        JsonElement actual = new ObjectMapper().treeToValue(input, JsonElement.class);
        assertEquals(expected, actual);
    }

    @JsonDeserialize(using = JsonElement.MyDeserializer.class)
    public abstract static class JsonElement {

        public static class JsonNull extends JsonElement {

            public static final JsonNull INSTANCE = new JsonNull();
        }

        public static final class MyDeserializer extends JsonDeserializer<JsonElement> {

            @Override
            public JsonElement deserialize(JsonParser jp, DeserializationContext dc) {
                throw new UnsupportedOperationException("Not needed for this example");
            }

            @Override
            public JsonElement getNullValue(DeserializationContext ctxt) {
                return JsonNull.INSTANCE;
            }
        }
    }
}
@andpal andpal added the to-evaluate Issue that has been received but not yet evaluated label Dec 5, 2020
@andpal andpal changed the title v(JsonNode, Class) no longer invokes JsonDeserializer::getNullValue(DeserializationContext) ObjectMapper::treeToValue(JsonNode, Class) no longer invokes JsonDeserializer::getNullValue(DeserializationContext) Dec 5, 2020
@cowtowncoder
Copy link
Member

Looks like this changed in a fix for #2430, as an optimization; but not intending to change logic.
Will see what is the best way to fix.

@cowtowncoder cowtowncoder added 2.12 and removed to-evaluate Issue that has been received but not yet evaluated labels Dec 9, 2020
@cowtowncoder cowtowncoder changed the title ObjectMapper::treeToValue(JsonNode, Class) no longer invokes JsonDeserializer::getNullValue(DeserializationContext) ObjectMapper.treeToValue() no longer invokes JsonDeserializer.getNullValue() Dec 9, 2020
@cowtowncoder cowtowncoder modified the milestones: 1.9.13, 2.12.1 Dec 9, 2020
@cowtowncoder
Copy link
Member

Fixed for 2.12.1 -- thank you for reporting the issue!

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

No branches or pull requests

2 participants