InvalidDefinitionException: Cannot construct instance of `com.vehicle.datatransferobject.VehicleDTO`

元气小坏坏 提交于 2020-06-25 21:18:28

问题


In the REST endpoint I'm building in Spring Boot, I'm trying to pass my vehicleDTO to my controller. But before it reaches my controller, there is an error.

InvalidDefinitionException: Cannot construct instance of com.vehicle.datatransferobject.VehicleDTO (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

vehicleDTO

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.myvehicle.EngineType;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class VehicleDTO {

    @JsonIgnore
    private Long id;

    @NotNull(message = "vehiclenumber can not be null!")
    private String vehiclenumber;

    @Min(2)
    @NotNull(message = "Seat count can not be less than 2!")
    private Integer vehicleseatcount;

    @NotNull(message = "Engine Type can not be null!")
    private EngineType enginetype;

    @Max(5)
    private Integer vehiclerating;



    private VehicleDTO(Long id, String vehiclenumber, Integer vehicleseatcount, EngineType enginetype,Integer vehiclerating){
        this.vehiclenumber=vehiclenumber;
        this.vehicleseatcount=vehicleseatcount;
        this.enginetype=enginetype;
        this.vehiclerating=vehiclerating;
        this.id=id;
    }

    public static VehicleDTOBuilder newBuilder()
    {
        return new VehicleDTOBuilder();
    }

    @JsonProperty
    public Long getId() {
        return id;
    }


    public String getvehiclenumber() {
        return vehiclenumber;
    }


    public Integer getvehicleseatcount() {
        return vehicleseatcount;
    }


    public EngineType getEnginetype() {
        return enginetype;
    }



    public Integer getvehiclerating() {
        return vehiclerating;
    }




    public static class VehicleDTOBuilder{

        private Long id;
        private String vehiclenumber;
        private Integer vehicleseatcount;
        private EngineType enginetype;
        private Integer vehiclerating;

        public VehicleDTOBuilder setId(Long id) {
            this.id = id;
            return this;
        }
        public VehicleDTOBuilder setvehiclenumber(String vehiclenumber) {
            this.vehiclenumber = vehiclenumber;
            return this;
        }
        public VehicleDTOBuilder setvehicleseatcount(Integer vehicleseatcount) {
            this.vehicleseatcount = vehicleseatcount;
            return this;
        }
        public VehicleDTOBuilder setEnginetype(EngineType enginetype) {
            this.enginetype = enginetype;
            return this;
        }
        public VehicleDTOBuilder setvehiclerating(Integer vehiclerating) {
            this.vehiclerating = vehiclerating;
            return this;
        }


        public VehicleDTO createVehicleDTO()
        {
            return new VehicleDTO(id, vehiclenumber, vehicleseatcount, enginetype,vehiclerating);
        }

    }

}

My DTO has an Enum type called EngineType

public enum EngineType {
    ELECTRIC, DIESEL
}

My controller looks like this

@PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public VehicleDTO addvehicle(@Valid @RequestBody VehicleDTO vehicleDTO) 
    {
        VehicleDO vehicleDO = Mapper.VehicleDO(vehicleDTO);
        return Mapper.makeVehicleDTO(Service.addvehicle(vehicleDO));
    }

回答1:


This exception :

InvalidDefinitionException: Cannot construct instance of com.vehicle.datatransferobject.VehicleDTO (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

means that Jackson didn't find a way to instantiate VehicleDTO that is the default constructor (no arg constructor) or a JsonCreator.
As you use a builder pattern you will configure the VehicleDTO class to make Jackson to instantiate VehicleDTO with the VehicleDTOBuilder such as :

@JsonDeserialize(builder = VehicleDTO.VehicleDTOBuilder.class)
public class VehicleDTO {
      ...         
}

And annotate your builder with JsonPOJOBuilder as :

@JsonPOJOBuilder(buildMethodName = "createVehicleDTO", withPrefix = "set")
public static class VehicleDTOBuilder{ 
   ...
}

According to the javadoc, JsonPOJOBuilder is :

used to configure details of a Builder class: instances of which are used as Builders for deserialized POJO values, instead of POJOs being instantiated using constructors or factory methods. Note that this annotation is NOT used to define what is the Builder class for a POJO: rather, this is determined by JsonDeserialize.builder() property of JsonDeserialize.




回答2:


I faced this error when I used Lombok's @Builder and @Data annotations together on a POJO class that is used for connecting to an API (either for consuming or for providing response)

I removed the @Builder annotation and then it is working fine




回答3:


In my case:

InvalidDefinitionException: Cannot construct instance of com.vehicle.datatransferobject.VehicleDTO (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

for the above exception, I just write Default Constructor which instantiates class and solved the problem.

Default Constructor:

public VehicleDTO() {
        super();
        // TODO Auto-generated constructor stub
    }


来源:https://stackoverflow.com/questions/51368115/invaliddefinitionexception-cannot-construct-instance-of-com-vehicle-datatransf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!