2

I have a problem related to:

De-serializing JSON to polymorphic object model using Spring and JsonTypeInfo annotation

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id '[' as a subtype

The solutions provided there didn't work for me. I have the following DTO:

public class QuestionaireAnswersDTO {

    @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.EXISTING_PROPERTY)
    @JsonSubTypes({
        @JsonSubTypes.Type(name = "single", value = SingleChoiceAnswerDTO.class),
        @JsonSubTypes.Type(name = "multi", value = MultipleChoiceAnswerDTO.class)
    })

    public static abstract class QuestionaireAnswerDTO {
        String answerId;
        String name;

        public String getAnswerId() {
            return answerId;
        }

        public void setAnswerId(String answerId) {
            this.answerId = answerId;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    String questionnaireId;

    List<QuestionaireAnswerDTO> answers;

    public String getQuestionnaireId() {
        return questionnaireId;
    }

    public void setQuestionnaireId(String questionnaireId) {
        this.questionnaireId = questionnaireId;
    }

    public List<QuestionaireAnswerDTO> getAnswers() {
        return answers;
    }

    public void setAnswers(List<QuestionaireAnswerDTO> answers) {
        this.answers = answers;
    }

with those subclasses:

public static class SingleChoiceAnswerDTO extends QuestionaireAnswerDTO {
        @Nullable
        String selectedOption;

        public String getSelectedOption() {
            return selectedOption;
        }

        public void setSelectedOption(String selectedOption) {
            this.selectedOption = selectedOption;
        }
    }

    public static class MultipleChoiceAnswerDTO extends QuestionaireAnswerDTO {
        List<String> selectedOptions;

        public List<String> getSelectedOptions() {
            return selectedOptions;
        }

        public void setSelectedOptions(List<String> selectedOptions) {
            this.selectedOptions = selectedOptions;
        }
    }

Now I wanted to write a test using this json object:

{
   "questionnaireId":"questionnaire1",
   "answers":[
      {
         "name":"single",
         "answerId":"Question1",
         "selectedOption":"Yes"
      },
      {
         "name":"multi",
         "answerId":"Question3",
         "selectedOptions":[
            "yes",
            "no"
         ]
      }
   ]
}

Using this test:

JsonFactory factory = new JsonFactory();
factory.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
ObjectMapper mapper = new ObjectMapper(factory);
mapper.registerSubtypes(QuestionaireAnswersDTO.SingleChoiceAnswerDTO.class, QuestionaireAnswersDTO.MultipleChoiceAnswerDTO.class);
QuestionaireAnswersDTO result = mapper.readValue(testData, QuestionaireAnswersDTO.class);
String resultAsString = mapper.writeValueAsString(result);
System.out.println(resultAsString);

Which results in the following Error:

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type, (...) 
missing type id property '@class' (for POJO property 'answers')

Using the .registerSubtypes() method instead of JsonSubtypes didn't work here instead of JsonSubtypes. Same error occurs.

Lucas Winkler
  • 51
  • 1
  • 8
  • 1
    Both your mapping as well as your json is wrong. You specify that for the type the `class` property should be used and the full name should be included, your mapping doesn't reflect this. Nor does your JSON have a `@class` property to match your configuration. I suggest you first write a test that writes JSON for a set of answers you want and compare that with what you manually have written. – M. Deinum Jul 12 '22 at 09:00
  • Did that and this worked good for me. Set use to JsonTypeInfo.Id.NAME and property = "type" and added type to the testJson string. Thanks – Lucas Winkler Jul 12 '22 at 14:21

0 Answers0