Konsumierer
Konsumierer

Reputation: 1304

Jackson 1.9.0: JsonTypeInfo for abstract class not working with Lists

Using this abstract class:

@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({ @JsonSubTypes.Type(value = PostingTaskInstanceDto.class, name = "TI") })
public abstract class BasePostingDto {}

and this inherited class:

public class PostingTaskInstanceDto extends BasePostingDto {}

I get correct serialization for a single object. This works, using Spring-MVC:

@RequestMapping("/{id}")
@ResponseBody
public BasePostingDto findById(@PathVariable("id") Long id) {
    return createDto(postingService.findById(id));
}

But if I retrieve a List of BasePostingDto from the remote controller, the type property is missing:

@RequestMapping("/by-user/all")
@ResponseBody
public List<BasePostingDto> findByUser() {
    return createDtoList(postingService.findByUser(AuthUtils.getUser()));
}

Why is this and how can I force the type property?

Update: the type property is also included if I change List<BasePostingDto> to BasePostingDto[], however I would prefer to go with the List.

Upvotes: 1

Views: 1571

Answers (1)

StaxMan
StaxMan

Reputation: 116630

It sounds like the framework you are using (and which uses Jackson under the hood) is not passing full generics-aware type information.

I don't know how that can be fixed (it is problem with integration by framework, and not something Jackson can address), but the usual work around is for you to use sub-class of List:

public class PostingDtoList extends List<BasePostingDto> { }

and use that in signature, instead of generic type. This solves the issue because then the generic type signature is retained (since it is stored in super type declaration, and accessible via type-erased PostingDtoList class!).

In generally I think it is best to avoid using generic List and Map types as root type (and instead use POJO); partly because of problems issued (there are bigger problems when using XML for example). But it can be made to work if need be.

Upvotes: 2

Related Questions