Skip to content

Inconsistent BeanPropertyDefinition#couldDeserialize and actual deserialization behavior starting from 2.17 #4597

Closed
@kaqqao

Description

@kaqqao

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

A bean property with an inaccessible (private) field and an implicit constructor returns true from BeanPropertyDefinition#couldDeserialize in 2.16.1, and false in 2.17.1. Yet both versions deserialize the bean and the field just fine. So the meta model and the deserializer behavior are inconsistent.
This is a regression of sorts, but perhaps intentional? Specifically, this line has been added in 2.17 (despite the comment claiming "since 2.16") to address #736.

Version Information

2.17.1

Reproduction

public static class Book {

    private String title;
    private int serial;


    public Book(String title, int serial) {
        this.title = title;
        this.serial = serial;
    }

    public String getTitle() {
        return title;
    }

    public int getSerial() {
        return serial;
    }
}

public static void main(String[] args) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper().registerModule(new ParameterNamesModule());
    JavaType bookType = mapper.getTypeFactory().constructType(Book.class);
    BeanDescription desc = mapper.getDeserializationConfig().introspect(bookType);
    boolean deserializable = desc.findProperties().get(0).couldDeserialize();
    System.out.println(deserializable); //true in 2.16, false in 2.17
    Book book = mapper.readValue("{\"title\":\"boom\", \"serial\":123}", Book.class); //works equally in both
}

Expected behavior

I'd expect bean deserialization to fail if BeanPropertyDefinition#couldDeserialize == false for one of the implicated fields.
Or, alternatively, BeanPropertyDefinition#couldDeserialize to return true if a usable bound constructor parameter is found.

Additional context

I am using Jackson's meta model to introspect Java types and create equivalent GraphQL types. For types used as inputs, it is important to know what fields are deserializable, as non-deserializable fields should not be mapped to GraphQL. For this reason, I have an extensive suite of tests for all sorts of Java types and deserialization configurations, and one of the tests caught this change in Jackson 2.17.

Metadata

Metadata

Assignees

No one assigned

    Labels

    to-evaluateIssue that has been received but not yet evaluated

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions