Deserializing Guava’s Table with Jackson throws "JsonMappingException: No suitable constructor found for type"

I’m using jackson-datatype-guava. I’m trying to deserialize a Table from JSON, but I’m getting an exception.

My code is:

public void jsonTable() throws IOException {
    Table<String, String, String> table = HashBasedTable.create();
    table.put("row1", "col1", "cell11");
    table.put("row1", "col2", "cell12");
    table.put("row2", "col1", "cell21");
    table.put("row2", "col2", "cell22");

    ObjectMapper mapper = new ObjectMapper()
            .registerModule(new GuavaModule());

    String tableJson = mapper.writeValueAsString(table);

    Table<String, String, String> deserializedTable = mapper.readValue(tableJson, HashBasedTable.class);

The exception thrown at the last line is:

com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
 at [Source: {"row1":{"col2":"cell12","col1":"cell11"},"row2":{"col2":"cell22","col1":"cell21"}}; line: 1, column: 2]
    at com.fasterxml.jackson.databind.JsonMappingException.from(
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(
    at com.gk.dfm.repository.impl.JsonTableTest.jsonTable(

It makes sense, since HashBasedTable has no default constructor. We should construct it using HashBasedTable.create(). How can I tell it to Jackson though?

On this page I found how to deserialize Guava’s Multimap:

public void convert() throws JsonParseException, JsonMappingException,
        JsonProcessingException, IOException {

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new GuavaModule());

    Multimap<String, NavItem> navs = objectMapper.readValue(
                    Multimap.class, String.class, NavItem.class));;

    assertThat(navs.keys(), hasItems("123455", "999999"));

How can I apply it to a Table? There is no such thing as constructTableLikeType.

Source: java

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.