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.

`@JsonValue` with integer for enum does not deserialize correctly

See original GitHub issue

The Javadoc for @JsonValue states that it is the only required annotation to both serialize and deserialize enums as something other than their name or ordinal:

when use for Java enums, one additional feature is that value returned by annotated method is also considered to be the value to deserialize from, not just JSON String to serialize as. This is possible since set of Enum values is constant and it is possible to define mapping, but can not be done in general for POJO types; as such, this is not used for POJO deserialization.

The Javadoc also states that it can be applied to any scalar type:

Usually value will be of a simple scalar type (String or Number), but it can be any serializable type (Collection, Map or Bean).

However, annotating an enum like below will fail to deserialize – Jackson appears to interpret the integer as the ordinal of the enum.

public enum Type {
    A(2),
    B(3);
    private final int value;
    Type(final int value) { this.value = value; }
    @JsonValue public int value() { return this.value; }
}

When attempting to deserialize an enum like the above example, on Jackson 2.9.2, I receive the following stack trace: (slightly anonymized)

com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `com.example.Type` from number 3: index value outside legal index range [0..1]
                                                                                 at [Source: (InputStreamReader); line: 1, column: 60] (through reference chain: java.util.ArrayList[0]->com.example.Pojo["type"])
                                                                                 at com.fasterxml.jackson.databind.DeserializationContext.weirdNumberException(DeserializationContext.java:1563)
                                                                                 at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdNumberValue(DeserializationContext.java:953)
                                                                                 at com.fasterxml.jackson.databind.deser.std.EnumDeserializer.deserialize(EnumDeserializer.java:200)
                                                                                 at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeSetAndReturn(MethodProperty.java:149)

If I add a @JsonCreator to a static method that matches the value to the internal field, the enum can be deserialized correctly. However that is more code I would rather not maintain if possible.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:34
  • Comments:25 (10 by maintainers)

github_iconTop GitHub Comments

32reactions
millevladacommented, Dec 7, 2018

Hi, I had same issue today, I managed to resolve that using this 2 annotations implemented within my int coded enum:

public enum MyEnum {
    SOME_MEMBER1(10),
    SOME_MEMBER2(15),

    private int code;

    MyEnum(int code) {
       this.code = code;
    }

   public int getCode() {
      return code;
   }

   @JsonValue
   public int toValue() {
        return getCode();
   }

   public static MyEnum forCode(int code) {
       for (MyEnum element : values()) {
          if (element.code == code) {
             return element;
          }
      }
      return null; //or throw exception if you like...
   }

   @JsonCreator
   public static MyEnum forValue(String v) {
       return MyEnum.forCode(Integer.parseInt(v));
   } 
}

Hope that helps someone else too, I did spent quite some time to find the variant that works… Cheers 😉

2reactions
joaoecommented, Nov 17, 2018

Hi. My issue is exactly the same as the one described originally.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Jackson: Serialize and deserialize enum values as integers
It should work by specifying JsonValue mapper. public enum State { OFF, ON, UNKNOWN; @JsonValue public int toValue() { return ordinal(); } }....
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 >
Serialize and Deserialize Enums with Jackson - Javatpoint
In this section, we will understand how we can serialize and deserialize Java Enums by using Jackson 2. In Java, Enumeration is a...
Read more >
Serializing and Deserializing Enumerations with Json.NET
This article shows you how to serialize and deserialize enums with Json.NET. ... that the entity is serialized and deserialized correctly.
Read more >
How to write custom converters for JSON serialization - .NET
The factory pattern is for converters that handle type Enum or open ... JsonException: The JSON value could not be converted to System....
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