vavr-io / vavr-jackson

Jackson datatype module for Vavr
Apache License 2.0
97 stars 35 forks source link

Nested maps are deserialized as java maps #109

Open heldev opened 7 years ago

heldev commented 7 years ago

Hi, It looks like that it's impossible right now to deserialize a JSON as vavr map tree, because only top level elements are deserialized as javaslang collections, deeper levels are java containers:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import javaslang.collection.List;
import javaslang.collection.Map;
import javaslang.jackson.datatype.JavaslangModule;
import org.junit.Test;

import java.io.IOException;

import static org.assertj.core.api.Assertions.assertThat;

public class VavrJacksonTest {

    private static final String JSON = "[\n" +
            "   {\n" +
            "        \"field1\": \"val1\",\n" +
            "        \"complexField\": {\n" +
            "            \"subField1\": \"subValue1\",\n" +
            "            \"subField2\": \"subValue2\"\n" +
            "        }\n" +
            "    }\n" +
            "]";

    @Test
    public void nested_maps_should_be_javaslang_maps() throws IOException {
        List<Map<String, Object>> listOfMapTrees = new ObjectMapper()
                .registerModule(new JavaslangModule())
                .readValue(JSON, new TypeReference<List<Map<String, Object>>>() {});

        assertThat(listOfMapTrees.get().apply("complexField")).isInstanceOf(Map.class);
        //Expecting:
        // <{"subField1"="subValue1", "subField2"="subValue2"}>
        //to be an instance of:
        // <javaslang.collection.Map>
        //but was instance of:
        // <java.util.LinkedHashMap>
    }
}
ruslansennov commented 7 years ago

This is expected behavior. By default, all JSON objects are deserialized to java.util.LinkedHashMap.

You can try using

new TypeReference<List<Map<String, Map<String,String>>>>() {}

instead of

new TypeReference<List<Map<String, Object>>>() {}

(unfortunately your example will fail because val1 is not a map)

heldev commented 7 years ago

I understand that there is, probably, some technical limitation from the jackson side, but this issue automatically breaks #75 deserialize(serialize(o)) equals o rule and gives a really hard time in some cases. Would it be possible to fix it ?

ruslansennov commented 7 years ago

Would it be possible to fix it ?

Up to now I have no idea about how that issue should be fixed. Maybe tests will be produced without nested cases only...

bduisenov commented 6 years ago

Hi @ruslansennov, do you have any updates on this? @heldev did you find a solution?

heldev commented 6 years ago

@bduisenov, no, not really :-/

dbaltor commented 3 years ago

You might find this Stackoverflow answer useful.