Reputation: 83
I’m trying to deserialize the following:
{
"type":"GIQuestionnaire",
"id":6051,
"questions":[
{
"type":"IncludeExcludeQuestion",
"id":24057,
"answers":[
{
"type":"IncludeExcludeAnswer",
"id":101497
},
{
"type":"IncludeExcludeAnswer",
"id":101496
}
]
}
]
}
Which results in this error:
java.lang.AssertionError: Can not handle managed/back reference 'questionnaire-questions': value deserializer is of type ContainerDeserializerBase, but content type is not handled by a BeanDeserializer (instead it's of type com.foo.questionnaire.json.QuestionDeserializer)
The Junit test:
@Test
public void testDeserializeQuestionnaire() {
ObjectMapper mapper = new ObjectMapper();
GIQuestionnaire q = manager.createGIQuestionnaire(…);
try
{
String json = mapper.writeValueAsString(q);
assertTrue(q.equals(mapper.readValue(json, GIQuestionnaire.class)));
} catch (Exception e) {
fail(e.getMessage());
}
}
A Questionnaire contains a Set (implemented as TreeSet) of Question objects. A Question contains a Set (TreeSet) of Answer objects.
Here are the relevant snippets of code that show how I used Jackson annotations:
// Questionnaire abstract base class
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type")
@JsonSubTypes({
@JsonSubTypes.Type(value=GIQuestionnaire.class, name="GIQuestionnaire"),
@JsonSubTypes.Type(value=PolicyQuestionnaire.class, name="PolicyQuestionnaire")
})
public abstract class Questionnaire implements Serializable {
@JsonManagedReference("questionnaire-questions")
@JsonDeserialize(as = TreeSet.class, contentAs = Question.class)
private Set<Question> questions = new TreeSet<>();
// … remainder omitted for brevity
}
// Question abstract base class
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = EntityQuestion.class, name = "EntityQuestion"),
@JsonSubTypes.Type(value = IncludeExcludeQuestion.class, name = "IncludeExcludeQuestion")
})
@JsonDeserialize(using = QuestionDeserializer.class)
public abstract class Question implements Comparable<Question>, Serializable {
@JsonBackReference("questionnaire-questions")
private Questionnaire questionnaire;
@JsonManagedReference("question-answers")
@JsonDeserialize(as = TreeSet.class, contentAs = Answer.class)
private Set<Answer> answers = new TreeSet<>();
// … remainder omitted for brevity
}
// Answer abstract base class
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = EntityAnswer.class, name = "EntityAnswer"),
@JsonSubTypes.Type(value = IncludeExcludeAnswer.class, name = "IncludeExcludeAnswer")
})
@JsonDeserialize(using = AnswerDeserializer.class)
public abstract class Answer implements Comparable<Answer>, Serializable {
@JsonBackReference("question-answers")
private Question question;
// … remainder omitted for brevity
}
public class QuestionDeserializer extends JsonDeserializer<Question> {
@Override
public Question deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
//deserialize a Question to a concrete instance
}
}
public class AnswerDeserializer extends JsonDeserializer<Answer> {
@Override
public Answer deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
//deserialize an Answer to a concrete instance
}
}
Where am I going wrong with my annotations and/or Deserializers?
Upvotes: 1
Views: 1630
Reputation: 2426
What if you try, very handy interface implementation @JsonIdentityInfo
which is provided in jackson 2 library?
@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Answer { ....
@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Question { ....
in maven
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.0.2</version>
</dependency>
Upvotes: 0
Reputation: 31
According to the Jackson WIKI the combination of polymorphic deserialization and @JsonManagedReference / @JsonBackReference is not supported.
Currently (as of version 1.6.0) combination of abstract types (with polymorphic handling using @JsonTypeInfo) do not work with this feature
See also a recent issue JIRA-890 in the Jackson issue tracker.
Upvotes: 3