We previously had the following field in our entity bean:
@DbJsonB(mutationDetection = MutationDetection.SOURCE)
@Column(columnDefinition = "JSONB", nullable = false)
private Map<OurEnum, String> params = new LinkedHashMap<>();
This worked without any serialization or deserialization issues. But, after changing the value type from String to Object:
@DbJsonB(mutationDetection = MutationDetection.SOURCE)
@Column(columnDefinition = "JSONB", nullable = false)
private Map<OurEnum, Object> params = new LinkedHashMap<>();
deserialization of the map keys became broken. At runtime, the map keys are deserialized as String instead of OurEnum.
The issue appears to be caused by the following logic in DefaultTypeManager (around line 372):
private boolean isMapValueTypeObject(Type genericType) {
Type[] typeArgs = ((ParameterizedType) genericType).getActualTypeArguments();
return Object.class.equals(typeArgs[1]) || "?".equals(typeArgs[1].toString());
}
Because the value type is Object, this condition evaluates to true, which causes the type manager to use ScalarTypeJsonMap. As a result, it does not fall back to ScalarJsonMapper.
I believe there are two possible ways to resolve this:
- Add enum key support to
ScalarTypeJsonMap to ensure that map keys can be properly deserialized back into enum types instead of defaulting to String.
- Refine
isMapValueTypeObject() logic and update the check to also take the key type into account, so that ScalarTypeJsonMap is only used for cases like:
This would allow cases like:
to continue using ScalarJsonMapper, preserving correct enum deserialization.
Ebean version: 17.3.0, with PGSQL DB
We previously had the following field in our entity bean:
This worked without any serialization or deserialization issues. But, after changing the value type from
StringtoObject:deserialization of the map keys became broken. At runtime, the map keys are deserialized as
Stringinstead ofOurEnum.The issue appears to be caused by the following logic in
DefaultTypeManager(around line 372):Because the value type is
Object, this condition evaluates totrue, which causes the type manager to useScalarTypeJsonMap. As a result, it does not fall back toScalarJsonMapper.I believe there are two possible ways to resolve this:
ScalarTypeJsonMapto ensure that map keys can be properly deserialized back into enum types instead of defaulting toString.isMapValueTypeObject()logic and update the check to also take the key type into account, so thatScalarTypeJsonMapis only used for cases like:This would allow cases like:
to continue using
ScalarJsonMapper, preserving correct enum deserialization.Ebean version:
17.3.0, with PGSQL DB