question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Immutable object deserialization should be possible without @JsonCreator when the creator is unambiguous.

See original GitHub issue

Hello, where I work we tend to only use immutable objects with all-args constructor. In order to deserialize such object, we must either add annotations like @JsonCreator to the actual class or when it comes from a library, we must create mix-ins.

Consider the following example class:

public final class Example {
  private final String field;
  private final String text;

  @JsonCreator
  public Example(@JsonProperty("field") String field,  @JsonProperty("text")String text) {
    this.field = field;
    this.text = text;
  }

  public String getField() {
    return field;
  }

  public String getText() {
    return text;
  }
}

Such example will deserialize nicely, but it would be great if there was no need to add anything to the class itself, because:

  • when creating domain classes in some low level module we wouldn’t want jackson dependencies yet
  • when using external library its not possible to edit class
  • above can be worked around with mix-ins, but this creates a lot of non-testable and probably not necessary code

Actually there already seems to be a deserialization feature that gets me halfway where I want and we can skip the @JsonProperty annotations by configuring ObjectMapper:

new ObjectMapper()
        .registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES))

However if the @JsonCreator annotation is removed, it will fail, even though there is only a single constructor. I would assume it should be given a try if there is no default nor @JsonCreator annotated method.

In my opinion such scenario should be possible to handle without any additions to the class itself. If not by default, then by configuring a proper deserialization features on ObjectMapper.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
cowtowncodercommented, Oct 9, 2020

Yes, so, #1498 tests are under:

src/test/java/com/fasterxml/jackson/databind/deser/creators/ConstructorDetector1498Test.java

and configuration setting to look for is ConstructorDetector.PROPERTIES. That should actually only matter for 1-argument case (2-argument case should already have worked, iff parameter names are detected) but worth enabling to avoid confusion for that case.

Setting is done using something like:

ObjectMapper mapper = JsonMapper.builder()
    .setConstructorDetector(ConstructorDetector.PROPERTIES)
    .build();

If you can verify this locally with 2.12.0-SNAPSHOT that’d be good; if it does not I would like to see specific test case.

Closing this for now assuming implementation works.

0reactions
cowtowncodercommented, Oct 16, 2020

@lukaszpierog Yeah, it is bit odd that default is such that information is left out and not the other way around. Although there may be legit reasons wrt backwards-compatibility of bytecode – perhaps some older tools have problem with inclusion.

But at least the mystery is solved.

It would be nice to have some mechanism of indicating likely issue, but this may be tricky. Problem would be reported if constructor was marked with just @JsonCreator. … I wonder if there was a way to indicate this, however, for special case of not having anything but one constructor; has properties (indicated by getter) and no other way to instantiate a value. This might be possible to detect reliably enough not to cause false alarms.

Will file an issue for that idea.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Deserialize Immutable Objects with Jackson - Baeldung
In this quick tutorial, we'll show two different ways of deserializing immutable Java objects with the Jackson JSON processing library.
Read more >
java - How to de/serialize an immutable object without default ...
To let Jackson know how to create an object for deserialization, use the @JsonCreator and @JsonProperty annotations for your constructors, like this:
Read more >
Jackson 2.12 Most Wanted (3/5) - cowtowncoder - Medium
Now: if @JsonCreator declaration was missing mode property, Jackson would try to figure out more likely of two modes — and the heuristics ......
Read more >
JSON serialization - Immutables
Integration works by generating @JsonCreator factory method and puts @JsonProperty annotations on immutable implementations. To enable this, you should use ...
Read more >
Management & Monitoring - Micronaut Documentation
It is possible to stop the Netty server without stopping the Application context. ... It allows the serialization and deserialization of object arrays....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found