Issue
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;
}
}
- 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 rangeexception). - 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).
Solution
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.
Answered By - Thomas
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.