Skip to content

Deserialization fails with version after 2.17.3 when DTO doesn't have no-args constructor #5332

@oleksiimiroshnyk

Description

@oleksiimiroshnyk

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

Looks like DTO without no-ars constructor is no longer able to to used for desirialization.

I'm upgrading my spring boot app and it seems jackson is also upgraded from 2.17.3 to 2.18+
My DTO/Bean looks like this:

public class Foo {
    private final String id;
    private String name;

!!!! NO DEFAULT CONSTRUCTOR !!!!!

    public Foo(String id) {
        this.id = id;
    }
    public Foo(String id, String name) {
        this.id = id;
        this.name = name;
    }
------------------- getters/setters
}

Here it is the isolated code that demonstrates the issue. It works fine with 2.17.3 but doesn't with anything beyond that (2.18, 2.19, 2.20)

        JsonMapper objectMapper = JsonMapper.builder()
                .constructorDetector(ConstructorDetector.DEFAULT).build();
        objectMapper.registerModule(new ParameterNamesModule());
        objectMapper.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        Foo foo = objectMapper.readValue("{}", Foo.class);

It also fails to deserialize

        String content = objectMapper.writeValueAsString(new Foo("blah", "qqq"));
        Foo foo1 = objectMapper.readValue(content, Foo.class);

The exception is the following:

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `org.example.Foo` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 2]
	at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
	at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1754)
	at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1379)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1512)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4931)

```

If I add no-args constructor it works. But in my application modifying DTO/Bean is not always possibe.

Is this expected ? I can't find the docs explaining why it should not work.

### Version Information

2.18.3

### Reproduction

My DTO/Bean looks like this:
```java
public class Foo {
    private final String id;
    private String name;

!!!! NO DEFAULT CONSTRUCTOR !!!!!

    public Foo(String id) {
        this.id = id;
    }
    public Foo(String id, String name) {
        this.id = id;
        this.name = name;
    }
------------------- getters/setters
}
```

Here it is the isolated code that demonstrates the issue. It works fine with 2.17.3 but doesn't with anything beyond that (2.18, 2.19, 2.20)
```java
        JsonMapper objectMapper = JsonMapper.builder()
                .constructorDetector(ConstructorDetector.DEFAULT).build();
        objectMapper.registerModule(new ParameterNamesModule());
        objectMapper.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        Foo foo = objectMapper.readValue("{}", Foo.class);
```
It also fails to deserialize 
```
        String content = objectMapper.writeValueAsString(new Foo("blah", "qqq"));
        Foo foo1 = objectMapper.readValue(content, Foo.class);
```

### Expected behavior

_No response_

### Additional context

_No response_

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions