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.

Deserializing enum by using String argument @JsonCreator method fails in 2.11.0

See original GitHub issue

I upgraded Jackson version from 2.10.1 to 2.11.0. After upgrading, deserializing enum by using a delegating method that is annotated @JsonCreator and has a single String argument, fails.

This is a sample code. In Jackson.version = 2.10.1, it will complete successfully. However, in Jackson.version = 2.11.0, it will fail by the following exception.

Exception in thread "main" com.fasterxml.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of `sample.EnumDeserializeTest$FooEnum`, problem: argument type mismatch
 at [Source: (String)"1"; line: 1, column: 1]

package sample;

import java.io.IOException;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.ObjectMapper;

public class EnumDeserializeTest {

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(FooEnum.FOO);
        mapper.readValue(json, FooEnum.class);
    }

    enum FooEnum {
        FOO(1);

        private final Integer code;

        FooEnum(Integer code) {
            this.code = code;
        }

        @JsonValue
        public Integer getCode() {
            return code;
        }

        @JsonCreator
        static FooEnum of(String code) {
            return FOO;
        }
    }
}

Is this behavior what you expect?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
cowtowncodercommented, May 30, 2020

@ta7uw It is unfortunate that code earlier somehow did work in this case – I am not quite sure why this is, I would have expected a runtime exception for mismatch. Oh, actually, I think I do know: code was assuming value is String, and using getText() or getValueAsText(), which in case of numeric value would have coerced quietly into String. This behavior prevented use of factory method that takes int or long value; which is I think why code was changed. Not sure if that could have been #2605, but I now thing I remember this change.

1reaction
cowtowncodercommented, May 29, 2020

@ta7uw I think I can see the problem: your JSON has number 1, but of method expects String value – this is a mismatch. I am not sure how things appeared to be working before, but to work shouldn’t you rather have:

        @JsonCreator
        static FooType of(int code) {
            return FOO;
        }

I do think that exception message in this case is not clear on specific mismatch, bit it does make sense to me.

Or, if you do not care about incoming value, have nominal type be Object (which matches any incoming JSON value)?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Jackson enum Serializing and DeSerializer - java
You should create a static factory method which takes single argument and annotate it with @JsonCreator (available since Jackson 1.2)
Read more >
SerializationFeature (jackson-databind 2.11.0 API) - javadoc.io
Feature that determines whether Java Enum values are serialized as numbers (true), or textual values (false). WRITE_ENUMS_USING_TO_STRING. Feature that ...
Read more >
How To Serialize and Deserialize Enums with Jackson
In this quick tutorial, we'll learn how to control the way Java Enums are serialized and deserialized with Jackson 2.
Read more >
ClassUtil (jackson-databind 2.11.0 API) - FasterXML
Helper method that encapsulate logic in trying to close output generator in case of failure; useful mostly in forcing flush()ing as otherwise error...
Read more >
Serialize and Deserialize Enums with Jackson - Javatpoint
If we serialize Enum by using the writeValueAsString() method, it will represent Java ... Deserializing JSON String to Enum Using @JsonCreator Annotation.
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