-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Search before asking
- I searched in the issues and found nothing similar.
Describe the bug
If we serialize an object which has a property of type Set, but referring EnumSet at runtime, then serialization uses CollectionSerializer instead of EnumSetSerializer for this property, when we activate default typing in ObjectMapper. This causes deserialization (using EnumSetDeserializer) to fail, since EnumSetDeserializer expects encoding of EnumSetSerializer, but not of CollectionSerializer.
Version Information
2.14.0 and above
Reproduction
If we run the below given test (java code), we get following error:
[ERROR] EnumSetSerializationTest.testSerialization:69 » MismatchedInput Cannot deserialize value of type com.fasterxml.jackson.databind.ser.enums.EnumSetSerializationTest$MyEnum
from Array value (token JsonToken.START_ARRAY
)
at [Source: REDACTED (StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION
disabled); line: 1, column: 191] (through reference chain: com.fasterxml.jackson.databind.ser.enums.EnumSetSerializationTest$EnumSetHolder["enumSet"]->java.util.RegularEnumSet[0])
package com.fasterxml.jackson.databind.ser.enums;
import com.fasterxml.jackson.databind.BaseMapTest;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.EnumSet;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
public class EnumSetSerializationTest extends BaseMapTest {
static enum MyEnum {
ITEM_A, ITEM_B;
}
static class EnumSetHolder {
private Set<MyEnum> enumSet; // use Set instead of EnumSet for type of this
public Set<MyEnum> getEnumSet() {
return enumSet;
}
public void setEnumSet(Set<MyEnum> enumSet) {
this.enumSet = enumSet;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof EnumSetHolder)) {
return false;
}
EnumSetHolder eh = (EnumSetHolder) o;
if (eh == this) {
return true;
}
if (enumSet == null) {
if (eh.getEnumSet() == null) {
return true;
} else {
return false;
}
} else {
if (eh.getEnumSet() == null) {
return false;
}
return enumSet.containsAll(eh.getEnumSet());
}
}
}
public void testSerialization() throws Exception {
ObjectMapper mapper = jsonMapperBuilder().build()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
// this type information is needed in json string, for this test
.activateDefaultTyping(BasicPolymorphicTypeValidator.builder().allowIfBaseType(Object.class).build(),
DefaultTyping.EVERYTHING);
EnumSetHolder enumSetHolder = new EnumSetHolder();
enumSetHolder.setEnumSet(EnumSet.allOf(MyEnum.class));
String jsonStr = mapper.writeValueAsString(enumSetHolder);
EnumSetHolder result = mapper.readValue(jsonStr, EnumSetHolder.class);
assertEquals(result, enumSetHolder);
}
}
Expected behavior
Above given test code should pass.
Additional context
As a workaround, if we make type of EnumSetHolder#enumSet property as EnumSet instead of Set, in the above given code, test passes.
No response