0

I try to serialize and deserialize enum. But Jackson uses natural Enum order value instead of my.

I uses Jackson 2.8.9.

My test enum:

public enum SomeEnum {

    SOME_VAL1(1),

    SOME_VAL2(2),

    SOME_VAL3(3),

    SOME_VAL4(4);

    private final Integer code;

    @JsonCreator
    SomeEnum(@JsonProperty("code") Integer code) {
        this.code = code;
    }

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

}

And this is my full code with failed test:

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

import java.io.IOException;

public class Program {

    public enum SomeEnum {

        SOME_VAL1(1),

        SOME_VAL2(2),

        SOME_VAL3(3),

        SOME_VAL4(4);

        private final Integer code;

        @JsonCreator
        SomeEnum(@JsonProperty("code") Integer code) {
            this.code = code;
        }

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

    }

    public static class EnumWrapper {

        private final SomeEnum someEnumVal;

        public EnumWrapper(@JsonProperty("someEnum") SomeEnum someEnumVal) {
            this.someEnumVal = someEnumVal;
        }

        @JsonProperty("someEnum")
        public SomeEnum getSomeEnumVal() {
            return someEnumVal;
        }
    }

    public static void main(String[] args) throws IOException {

        ObjectMapper mapper = new ObjectMapper();

        String inputJson = mapper.writeValueAsString(new EnumWrapper(SomeEnum.SOME_VAL3));
        EnumWrapper resultEnumWrapper =
                mapper.readValue(inputJson, EnumWrapper.class);

        if (resultEnumWrapper.getSomeEnumVal() != SomeEnum.SOME_VAL3) {
            System.out.println(resultEnumWrapper.getSomeEnumVal());
            System.out.println(inputJson);
            throw new RuntimeException("enum = " + resultEnumWrapper.getSomeEnumVal());
        }
    }
}

Why I have this wrong deserialization of enum? I uses @JsonProperty.

Max
  • 1,803
  • 3
  • 25
  • 39

2 Answers2

1

Try exposing a method with @JsonCreator, e.g.:

@JsonCreator
public static SomeEnum findByCode(final int code){
    for (final SomeEnum element : values()) {
        if (element.getCode().equals(code)) {
            return element;
        }
    }
    return null;
}
Darshan Mehta
  • 30,102
  • 11
  • 68
  • 102
  • it works, but has some problems. Firstly, it has O(N) complexity. Secondly, I have to write such code for each Enum. – Max Jun 27 '17 at 21:35
  • 1
    @Max not for each enum but only for those enums that have reference variables and need finding by reference values. Regarding O(N), you can hashmap all the values inside the enum and use `get`. – Darshan Mehta Jun 28 '17 at 08:11
  • Unless your enum has a million values, it doesn't matter. – Josh M. Aug 09 '19 at 19:35
0

what about using the method oriented declaration of Jackson and defining the setter with an input string, which will be internally instantiating the enum ?

private SomeEnum someEnum;

public void setSomeEnum(String value ){}
André
  • 172
  • 13