Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ModelMapper - Failed to instantiate instance of destination

I'm working with mongodb so I'm decoupling entities from presentation layer creating DTOs (with hibernate-validator annotations).

public abstract class UserDTO {

    private String id;      
    @NotNull
    protected String firstName;
    @NotNull
    protected String lastName;
    protected UserType type;
    protected ContactInfoDTO contact;
    protected List<ResumeDTO> resumes;

    public UserDTO(){}
    //...

I'm trying to retrive from db this concrete class

public class UserType1DTO extends UserDTO {

    private CompanyDTO company;

    public UserType1DTO(){
        super();
    }

    public UserType1DTO(String firstName, String lastName, ContactInfoDTO contact, CompanyDTO company) {
        super(UserType.type1, firstName, lastName, contact);
        this.company = company;
    }
    /...

Like this:

return mapper.map((UserType1) entity,UserType1DTO.class);

And I get this error about not being able to instanciate ResumeDTO

Failed to instantiate instance of destination *.dto.ResumeDTO. Ensure that *.dto.ResumeDTO has a non-private no-argument constructor.

ResumeDTO is similar to UserDTO, is an abstract class and has concrete classes for each user type. All they have constructors with no arguments. What is the problem?

like image 852
anat0lius Avatar asked Mar 02 '17 09:03

anat0lius


1 Answers

You are trying to map a concrete class to an abstract class, this will not work. You can not use as destination an Abstract Class. Why? It can not be instantiated. So you must use a concrete class

Definitively it wouldn't work a map with an Abstract Class destination:

mapper.map(entity, AbstractClass.class);
/*Error: java.lang.InstantiationException
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)*/

You must use a concrete class which extends the Abstract Class

public class ConcreteClass extends AbstractClass {
       //
}

And then map it to this concrete class:

mapper.map(entity, ConcreteClass.class);

More info:

Due to is not possible to insantiate an abstract class it will not work in desination properties neither.

There is an issue in Github related to this: https://github.com/jhalterman/modelmapper/issues/130

like image 129
Pau Avatar answered Nov 06 '22 05:11

Pau