Reputation: 547
I am trying to use Jackson to serialize entities with polymorphism. The serialized JSON string should include an additional "type" property with "groupA" or "groupB" as value, but it doesn't. My entities look like this:
@Entity
@Table(name = "\"group\"")
@Inheritance(strategy = InheritanceType.JOINED)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = GroupA.class, name = "groupA"),
@JsonSubTypes.Type(value = GroupB.class, name = "groupB")
})
@JsonSerialize(include = JsonSerialize.Inclusion.ALWAYS)
public class Group implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
// ...
}
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSerialize(include = JsonSerialize.Inclusion.ALWAYS)
public class GroupA extends Group {
//...
}
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSerialize(include = JsonSerialize.Inclusion.ALWAYS)
public class GroupB extends Group {
// ...
}
Do you know why the serializer does not add the type property?
Upvotes: 3
Views: 5876
Reputation: 547
The problem is the controller action:
@RequestMapping(...)
@ResponseBody
public Map<String, Object> getGroups() {
Map<String, Object> response = new HashMap<String, Object>();
List<Group> groups = magicallyRetrieveGroupsFromNarnia();
response.put("groups", groups);
response.put("status", Status.OK);
return response;
}
It returns a map of String-Object tuples. The MappingJackson2HttpMessageConverter throws this map into the ObjectMapper. The ObjectMapper doesn't care about @JsonTypeInfo for the supplied map contents, because it doesn't know about it. All it sees are type-erased List instances in uncomfortable Object-suits.
There are multiple ways to resolve this problem:
This JIRA issue helped me understand the problem: https://github.com/FasterXML/jackson-databind/issues/364
Upvotes: 8
Reputation: 1235
You may need to specify EXTERNAL_PROPERTY here, as the class in question has no "type" property.
Upvotes: 1
Reputation: 871
Perhaps you need a field "type" in your Group class? Like this:
private String type;
with getter and setter, of course
Upvotes: 0