2

I'm using the jackson library to map JSON into objects. I've simplified the problem a lot, this is what happens:

public class MyObject{

    public ForeignCollection<MySecondObject> getA(){
        return null;
    }

    public ForeignCollection<MyThirdObject> getB(){
        return null;
    }
}

I'm parsing the an empty JSON string:

ObjectMapper mapper = new ObjectMapper();
mapper.readValue("{}", MyObject.class);

On readValue, I get this Exception:

com.fasterxml.jackson.databind.JsonMappingException: Can not find a deserializer for non-concrete Collection type [collection type; class com.j256.ormlite.dao.ForeignCollection, contains [simple type, class com.test.MyThirdObject]]

This happens when I have two get methods in the MyObject class which return a ForeignCollection. Removing one of the get methods results in no exceptions.

I'm actually surprised by the fact that the mapper looks at the get methods, it should just set the fields I indicate.

What is happening here?

nhaarman
  • 98,571
  • 55
  • 246
  • 278
  • Sounds like the JSON mapper is trying to map all `get*` methods. Have you tried returning a `Collection` instead? You may have to annotate the JSON properties instead and not have one on `mySecondObjects`. http://stackoverflow.com/questions/4410470/how-can-i-serialize-this-json-using-jackson-annotations – Gray Feb 13 '13 at 18:48
  • Thanks for the annotation hint, that makes life a lot simpler! However, the problem hasn't been solved. I found something out, and modified the question a bit. – nhaarman Feb 14 '13 at 13:15
  • Where are your set methods? How would deserializer "just set" the fields without ones? Or are they just not shown? Type from setter or field should have precedence, although getter must also be considered as additional source for annotations and may be used to refine type. – StaxMan Feb 14 '13 at 16:15
  • I've removed as much as possible, I would have some fields like `@JsonProperty("name") private String myName`. – nhaarman Feb 14 '13 at 17:52

3 Answers3

4

You need to use the Guava module in your ObjectMapper. Here is the Maven dependency:

<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-guava</artifactId>
  <version>{whatever is the latest}</version>
</dependency>

In your code:

ObjectMapper mapper = new ObjectMapper();
// register module with object mapper
mapper.registerModule(new GuavaModule());

You can omit the @JsonDeserialize and @JsonSerialize annotations.

More info here.

barclay
  • 4,362
  • 9
  • 48
  • 68
2

I've fixed this by converting the ForeignCollection to a List:

private ForeignCollection<MyObject> myObjects;

public List<MyObject> getMyObjects(){
    return new ArrayList<MyObject>(myObjects);
}
nhaarman
  • 98,571
  • 55
  • 246
  • 278
1

You may need to define custom deserializer for ForeignCollection; or, if there is known implementation class, use annotation:

@JsonDeserialize(as=ForeignCollectionImpl.class)

to indicate which concrete sub-class to use for that abstract type.

StaxMan
  • 113,358
  • 34
  • 211
  • 239