Sanjeev
Sanjeev

Reputation: 215

Why Json ask for no argument constructor for Junit test?

I have a problem deserializing a JSON string using Jackson. I am getting Error : com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class RatingDMO]: can not instantiate from JSON object (need to add/enable type information?)

I have the fields mapped to the JSON file and parameters to it are available as properties AND have the same type.

Note :- If I provide the no-arg constructor(just for checking if it works), the Test works.

I can't provide/leave a default constructor in my code as I have few final fields in the model.

mapper.readValue(new File("ratingRequest.json"), RatingDMO.class);

POJO Class :

public class RatingDMO implements Serializable {
    
    private static final long serialVersionUID = -433016040176969496L;
    private String company;
    private String state;
    private String lob;
    private String channel;
    private String username;
    private String password;
    private String policyNumber;
    private long policyKey;
    private String transactionType;
    private String evaluationType;
    private String clientID;
    private String policyTerm;
    private String effectiveDate;
    private String policyXML;
    private String webXML;
    private String firstName;
    private String lastName;
    private String businessName;
    private String city;
    private String zip;
    private String effectiveDtStart;
    private String effectiveDtEnd;
    private String searchType;
    private String uuid;
    private List<String> policyStatusCodes;
    private Map<String,String> eAdvisorCoverages;
    private Map<String,String> customCoverages;
    private Map<String,String> defaultCoverages;
    private String action;
    private String type;
    private String selectedCoverage;
    private boolean motorClubMember;
    private String selectedSubCoveres;
    private boolean customRated;
    private final PolicyDMO policyDMO;
    private final String allInsuredInd;
    private final String medicareMediaidInd;
    private final boolean driversGreaterthan65;
         
    public PolicyRatingRequestDMO(PolicyDMO policyDMO, String allInsuredInd, String medicareMediaidInd, boolean driversGreaterthan65){
        this.policyDMO = policyDMO;
        this.allInsuredInd = allInsuredInd;
        this.medicareMediaidInd = medicareMediaidInd;
        this.driversGreaterthan65 = driversGreaterthan65;
    }
... }

Upvotes: 2

Views: 3793

Answers (1)

Ian Roberts
Ian Roberts

Reputation: 122364

By default Jackson's data binding will try to construct an object using a no-argument constructor and then fill in the object's properties from the corresponding bits of the JSON. You can override this behaviour with annotations

@JsonCreator
public PolicyRatingRequestDMO(@JsonProperty("policyInfo") PolicyDMO policyDMO,
         @JsonProperty("allInsuredInd") String allInsuredInd,
         @JsonProperty("medicareMediaidInd") String medicareMediaidInd,
         @JsonProperty("driversGreaterThan65") boolean driversGreaterthan65){
    this.policyDMO = policyDMO;
    this.allInsuredInd = allInsuredInd;
    this.medicareMediaidInd = medicareMediaidInd;
    this.driversGreaterthan65 = driversGreaterthan65;
}

The JsonCreator annotation tells Jackson which constructor to call, and its parameters are annotated with JsonProperty to indicate which properties in the JSON correspond to which parameters in the constructor. Additional properties in the JSON that do not correspond to constructor arguments will be injected via setters or direct field access as normal.

Upvotes: 12

Related Questions