Skip to content

Failing @JsonMerge with a custom Map #4922

Closed
@nlisker

Description

@nlisker

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    2.18Issues planned at 2.18 or later

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions