Json 无法反序列化一组多态对象(Jackson 2.1.2)

Json 无法反序列化一组多态对象(Jackson 2.1.2),json,serialization,jackson,Json,Serialization,Jackson,我正在尝试反序列化以下内容: { "type":"GIQuestionnaire", "id":6051, "questions":[ { "type":"IncludeExcludeQuestion", "id":24057, "answers":[ { "type":"IncludeExcludeAnswer", "id":101497

我正在尝试反序列化以下内容:

{
 "type":"GIQuestionnaire",
 "id":6051,   
 "questions":[
      {
        "type":"IncludeExcludeQuestion",
        "id":24057,
        "answers":[
            {
              "type":"IncludeExcludeAnswer",
               "id":101497
            },
            {
              "type":"IncludeExcludeAnswer",
               "id":101496
            }
         ]
      }
   ]
}
导致此错误的原因:

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)
Junit测试:

@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());
    }
}
问卷包含一组问题对象(实现为树集)。问题包含一组(树集)答案对象

以下是我如何使用Jackson注释的相关代码片段:

// 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
    }
}
//抽象基类
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“type”)
@JsonSubTypes({
@JsonSubTypes.Type(value=giquestionly.class,name=“giquestionly”),
@JsonSubTypes.Type(value=policyQuestionly.class,name=“policyQuestionly”)
})
公共抽象类实现了可序列化{
@JsonManagedReference(“问卷问题”)
@JsonDeserialize(as=TreeSet.class,contentAs=Question.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(使用=QuestionDeserializer.class)
公共抽象类问题实现了可比较的、可序列化的{
@JsonBackReference(“问卷问题”)
私人问卷;
@JsonManagedReference(“问题-答案”)
@JsonDeserialize(as=TreeSet.class,contentAs=Answer.class)
私有集答案=新树集();
//…为简洁起见,省略了余数
}
//答案:抽象基类
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“type”)
@JsonSubTypes({
@JsonSubTypes.Type(value=EntityAnswer.class,name=“EntityAnswer”),
@JsonSubTypes.Type(值=IncludeExcludeAnswer.class,name=“IncludeExcludeAnswer”)
})
@JsonDeserialize(使用=AnswerDeserializer.class)
公共抽象类Answer实现了可比较的、可序列化的{
@JsonBackReference(“问题-答案”)
私人问题;
//…为简洁起见,省略了余数
}
公共类提问反序列化程序扩展JsonDeserializer{
@凌驾
公共问题反序列化(JsonParser、JsonParser、DeserializationContext、DeserializationContext)引发IOException、JsonProcessingException{
//将问题反序列化为具体实例
}
}
公共类应答器反序列化器扩展JsonDeserializer{
@凌驾
公共应答反序列化(JsonParser、JsonParser、DeserializationContext、DeserializationContext)抛出IOException、JsonProcessingException{
//对具体实例的答案进行反序列化
}
}
注释和/或反序列化程序哪里出了问题?

根据说明,多态反序列化和@JsonManagedReference/@JsonBackReference的组合不受支持

目前(从版本1.6.0开始)抽象类型的组合(使用@JsonTypeInfo进行多态处理)不适用于此功能


另请参阅Jackson问题跟踪器中的最新一期。

如果您尝试使用Jackson 2库中提供的非常方便的接口实现
@JsonIdentityInfo
,会怎么样

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Answer { ....

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Question { ....
在马文

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.0.2</version>
</dependency>

com.fasterxml.jackson.core
杰克逊核心
2.0.2