Skip to content

constructorDetector seems to invalidate defaultSetterInfo for nullability #3241

@joca-bt

Description

@joca-bt

Was trying out the new constructor detector feature (https://cowtowncoder.medium.com/jackson-2-12-most-wanted-3-5-246624e2d3d0/) and stumbled upon the following issue.

I had this code which forbids nulls on deserialization:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;

public class Input {
    private final Boolean field;

    @JsonCreator
    public Input(Boolean field) {
        this.field = field;
    }
}

ObjectMapper objectMapper = JsonMapper.builder()
    .addModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES))
    .defaultSetterInfo(JsonSetter.Value.construct(Nulls.FAIL, Nulls.FAIL))
    .build();

objectMapper.readValue("{ \"field\": null }", Input.class); // throws InvalidNullException, as expected

and was trying to get rid of @JsonCreator with the following

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.cfg.ConstructorDetector;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;

public class Input {
    private final Boolean field;

    // @JsonCreator gone!
    public Input(Boolean field) {
        this.field = field;
    }

    public Boolean field() {
      return field;
    }
}

ObjectMapper objectMapper = JsonMapper.builder()
    .addModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES))
    .constructorDetector(ConstructorDetector.USE_PROPERTIES_BASED) // new!
    .defaultSetterInfo(JsonSetter.Value.construct(Nulls.FAIL, Nulls.FAIL))
    .build();

objectMapper.readValue("{ \"field\": null }", Input.class); // no error, field is assigned to null

Although I no longer need to annotate my class with @JsonCreator, my settings for nullability are ignored, which means I can't really use the new feature.

(Might be related with #3227?)

Metadata

Metadata

Assignees

No one assigned

    Labels

    2.18Issues planned at 2.18 or laterhas-failing-testIndicates that there exists a test case (under `failing/`) to reproduce the issueproperty-discoveryProblem with property discovery (introspection)

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions