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

Auto-detect multi-argument constructor with implicit names if it is the only visible creator #725

Closed
cowtowncoder opened this issue Mar 15, 2015 · 1 comment
Milestone

Comments

@cowtowncoder
Copy link
Member

As part of continuing work to more seamlessly support addition of argument name information (by JDK8, paranamer, or other mechanism), it makes sense to allow auto-detect of creators even without @JsonCreator annotation if:

  1. All parameters have name (implicit or explicit), or are marked as injectable AND
  2. There are no other visible constructors AND
  3. There is no default (no-arg) constructor (which otherwise would be detected regardless of visibility)

In addition, there is one practical limitation due to existing resolution rules:

  • Single-argument constructor will default to "delegating" constructor, so implicit names are only used if @JsonCreator is used to indicate "property-based" constructor use, or explicit names.

Note, too, that language modules (like jackson-module-scala) may refine rules for more accurate detection of the "main" constructor; this functionality refers to vanilla handling for Java.

@cowtowncoder cowtowncoder added this to the 2.6.0 milestone Mar 16, 2015
@cowtowncoder cowtowncoder changed the title Auto-detect multi-argument constructor with implicit names if the only visible creator Auto-detect multi-argument constructor with implicit names if it is the only visible creator Mar 16, 2015
@shmosel
Copy link

shmosel commented Nov 2, 2021

This fails when parameters are annotated with @JsonDeserialize or @JsonProperty.

Minimal test:

static class Person {
    Person(@JsonDeserialize String name, @JsonProperty int age) {}
}

@Test
void autoDetectWithDeserialize() throws IOException {
    new ObjectMapper()
            .registerModule(new ParameterNamesModule())
            .readValue("{\"name\":\"John\",\"age\":20}", Person.class);
}

Result:

Can not construct instance of ...$Person: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
 at [Source: {"name":"John","age":20}; line: 1, column: 2]
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of ...$Person: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
 at [Source: {"name":"John","age":20}; line: 1, column: 2]
	at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
	at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:1456)
	at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1012)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1205)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:314)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3798)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2842)

Tested in 2.8.5.

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