Deserialize enum from both Integer and String in Java

Viewed 300

I am adding a new code logic, using CDC (capture data change) events. A status field coming from the DB is represented as an int and should be deserialized into an enum. This is the enum:

public enum Status {

    ACTIVE(21),
    CANCELLED(22),
    EXPIRED(23),
    FAILED(24),
    PAUSED(25);

    private static final Map<Integer, Status> map = new HashMap<>();

    static {
        for (val value : Status.values()) {
            if (map.put(value.getId(), value) != null) {
                throw new IllegalArgumentException("duplicate id: " + value.getId());
            }
        }
    }

    public static Status getById(Integer id) {
        return map.get(id);
    }

    private Integer id;

    Status(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }
}
  1. The enum can't be "out of the box" serialized from Integer since it is not starting from 0 (receiving index value outside legal index range exception).
  2. Today we already have a flow that is receiving a String (e.g. "ACTIVE") and deserializing it successfully. I do not want to change/harm this capability.

I've tried to add @JsonCreator here:

@JsonCreator
public static SubscriptionStatus getById(Integer id) {
    return map.get(id);
}

But now it is impossible to deserialize String anymore. I prefer to have a simple solution rather than creating a custom deserializer for it (I assume there should be one).

1 Answers

Try something like this:

@JsonCreator
public static Status get(Object reference) {
  if( reference instanceof Number num) {
    return getById(num.intValue());
  } else if( reference instanceof String str) {
    //the string might contain the id as well, e.g. "21" for ACTIVE
    //so you might want to check the string for this, if this is expected
    return Enum.valueOf(Status.class, str);
  }
        
  return null;
}

This basically takes a value of any type, checks what it is and resolves the enum value accordingly.

Related