Jackson - @JsonTypeInfo property is being mapped as null?
jackson, java, json-deserialization
Solution
Finally, I've found the solution in the API Doc
Note on visibility of type identifier: by default, deserialization (use during reading of JSON) of type identifier is completely handled by Jackson, and is not passed to deserializers. However, if so desired, it is possible to define property visible = true in which case property will be passed as-is to deserializers (and set via setter or field) on deserialization.
So the solution was simply adding the 'visible' attribute as follows
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "exercise_type",
visible = true)
@JsonSubTypes({
@Type(value = ExerciseChoiceResponseDTO.class, name = "CHOICE"),
@Type(value = ExerciseQuestionResponseDTO.class, name = "QUESTION")})
public abstract class ExerciseMixIn
{}
Problem
Say I have the following JSON: ``` { "id":"decaa828741611e58bcffeff819cdc9f", "statement":"question statement", "exercise_type":"QUESTION" } ``` then, based on the `exercise_type` field, I want to instantiate different objects instances (subclasses of `ExerciseResponseDTO`). In order to do that, I tried creating this mix in: ``` @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "exercise_type") @JsonSubTypes({ @Type(value = ExerciseChoiceResponseDTO.class, name = "CHOICE"), @Type(value = ExerciseQuestionResponseDTO.class, name = "QUESTION")}) public abstract class ExerciseMixIn {} public abstract class ExerciseResponseDTO { private String id; private String statement; @JsonProperty(value = "exercise_type") private String exerciseType; // Getters and setters } public class ExerciseQuestionResponseDTO extends ExerciseResponseDTO {} public class ExerciseChoiceResponseDTO extends ExerciseResponseDTO {} ``` and then the mapper `ObjectMapper` as follows ``` ObjectMapper mapper = new ObjectMapper(); mapper.addMixIn(ExerciseResponseDTO.class, ExerciseMixIn.class); ``` but for some reason, this test fails: ``` ExerciseResponseDTO exercise = mapper.readValue(serviceResponse, ExerciseResponseDTO.class) Assert.assertTrue(exercise.getClass() == ExerciseQuestionResponseDTO.class); // OK Assert.assertEquals("decaa828741611e58bcffeff819cdc9f" exercise.getId()); // OK Assert.assertEquals("question statement", exercise.getStatement()); // OK Assert.assertEquals("QUESTION", exercise.getExerciseType()); // FAIL. Expected: "QUESTION", actual: null ``` seems like there's an issue specifically with the `exercise_type` attribute that's not being mapped for some reason, since all the other fields are being mapped just fine. Any idea what could it be causing this?