0

I'm trying to deserialize JSON Array, which is persisted into my MongoDB, to a Java object by using Jackson. I found many tutorials mentioned to handle this polymorphism by adding:

@JsonTypeInfo(use=Id.CLASS,property="_class")

to a Super-class. However, in my case, I can't be able to modify the Super-class. So, are there some solutions to solve it without modifying the Super-class? Here is my code:

public class User {

    @JsonProperty("_id")
    private String id;
    private List<Identity> identities; // <-- My List contains objects of an abstract class; Identity
    public User(){
        identities = new ArrayList<Identity>();
    }
    public static Iterable<User> findAllUsers(){
        return users().find().as(User.class); // Always give me the errors
    }
    /*More code*/
}

It always give me the error - Can not construct instance of securesocial.core.Identity, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information.

lvarayut
  • 13,963
  • 17
  • 63
  • 87

1 Answers1

0

You can use @JsonDeserilize annotation to bind a concrete implementation class to an abstract class. If you cannot modify your abstract class you can use the Jackson Mix-in annotations to tell Jackson how to find the implementation class.

Here is an example:

public class JacksonAbstract {
    public static class User {
        private final String id;
        private final List<Identity> identities;

        @JsonCreator
        public User(@JsonProperty("_id") String id, @JsonProperty("identities") List<Identity> identities) {
            this.id = id;
            this.identities = identities;
        }

        @JsonProperty("_id")
        public String getId() {
            return id;
        }

        public List<Identity> getIdentities() {
            return identities;
        }
    }

    public static abstract class Identity {
        public abstract String getField();
    }

    @JsonDeserialize(as = IdentityImpl.class)
    public static abstract class IdentityMixIn {
    }

    public static class IdentityImpl extends Identity {
        private final String field;

        public IdentityImpl(@JsonProperty("field") String field) {
            this.field = field;
        }

        @Override
        public String getField() {
            return field;
        }
    }

    public static void main(String[] args) throws IOException {
        User u = new User("myId", Collections.<Identity>singletonList(new IdentityImpl("myField")));
        ObjectMapper mapper = new ObjectMapper();
        mapper.addMixInAnnotations(Identity.class, IdentityMixIn.class);
        String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(u);
        System.out.println(json);
        System.out.println(mapper.readValue(json, User.class));
    }
}
Alexey Gavrilov
  • 10,593
  • 2
  • 38
  • 48