Closed
Description
Continuation of #4783.
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonMerge;
import com.fasterxml.jackson.databind.json.JsonMapper;
interface MyMap<K, V> extends Map<K, V> {}
class MapImpl<K, V> extends HashMap<K, V> implements MyMap<K, V> {}
class MapUtils {
static <K, V> MyMap<K, V> createMyMap() {
return new MapImpl<K, V>();
}
}
class MergeMap {
@JsonMerge // either here
MyMap<Integer, String> map = MapUtils.createMyMap();
@JsonMerge // or here
public MyMap<Integer, String> getMap() {
System.out.println("getMap");
return map;
}
@Override
public String toString() {
return map.toString();
}
public static void main(String[] args) throws Exception {
JsonMapper MAPPER = JsonMapper.builder().build();
var merge = new MergeMap();
merge.getMap().put(3, "ADS");
System.out.println(merge);
System.out.println(" == serializing --");
var string = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(merge);
System.out.println(string);
System.out.println(" == deserializing --");
var merge2 = MAPPER.readValue(string, MergeMap.class);
System.out.println(" == checking --");
System.out.println(merge2);
}
}
This fails in 2.18.2 with
getMap
{3=ADS}
== serializing --
getMap
{
"map" : {
"3" : "ADS"
}
}
== deserializing --
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot find a deserializer for non-concrete Map type [map type; class example.MyMap, [simple type, class java.lang.Integer] -> [simple type, class java.lang.String]]
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 1]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1888)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:321)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:284)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:174)
at com.fasterxml.jackson.databind.DeserializationContext.findNonContextualValueDeserializer(DeserializationContext.java:659)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:552)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:347)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:284)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:174)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:669)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:5048)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4918)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3860)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3828)
at example.MergeMap.main(MergeMap.java:49)
I'm not sure where @JsonMerge
should be placed - on the field or on the getter, but both failed.