2

I have 2 classes as such

class Parent {

   private final Optional<Child> child;
  
   @JsonCreator
   Parent(@JsonProperty("child") Optional<Child> child) {
         this.child = child;
   }
}

class Child {

   private final Optional<String> name;

   @JsonCreator
   Child(@JsonProperty("name")Optional<String> name){
     this.name = name;
   }

}

The json that I intend to deserialize into the Parent class looks like below:

{
  "child" : {
     "name" : "abc"
  }
}

To deserialize itself I am using the ObjectMapper:

ObjectMapper mapper = new ObjectMapper()
                .registerModule(new Jdk8Module());

However at runtime getting the exception below:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.util.Optional` (no Creators, like default constructor, exist): cannot deserialize from Object value

A lot of answer on stack suggest the use of registerModule like this one. Am I missing something in the use of registerModule?

1
  • Works fine in my environment. Might be usefull to provide your jackson dependencies stack with versions to find a problem. Do you use this mapper directly after setting a module? Or its a component of framework? Commented Dec 7, 2023 at 16:25

1 Answer 1

1

I think the problem lies somewhere else. Optionals are not quite intended to be a class parameters. They should be used as a method return values:

Of course, people will do what they want. But we did have a clear intention when adding this feature, and it was not to be a general purpose Maybe or Some type, as much as many people would have liked us to do so. Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent "no result", and using null for such was overwhelmingly likely to cause errors. The key here is the focus on use as a return type.

Source: https://blog.joda.org/2014/11/optional-in-java-se-8.html

So I think you should focus on serializing/deserializing the null values, and use optionals only as a return value from getter like this:

class Parent {

   private final Child child;
  
   @JsonCreator
   Parent(Child child) {
         this.child = child;
   }

   Optional<Child> getChild() {
      return Optional.ofNullable(child);
   }
}

class Child {

   private final String name;

   @JsonCreator
   Child(String name){
     this.name = name;
   }

   Optional<String> getName() {
      return Optional.ofNullable(name);
   }

}

If you really want to mark the property that it could be a null, then you may use @Nullable annotation from org.jetbrains package. Then, if you use Intellij Idea for coding, it would check for suspicious code fragments that may lead to NullPointerExcetpion.

Source: https://www.jetbrains.com/help/idea/annotating-source-code.html#contract-annotations

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.