Home > Back-end >  How do I make fields in DTO optional using lombok?
How do I make fields in DTO optional using lombok?

Time:07-12

So I have a DTO like this,

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@ToString
@JsonIgnoreProperties(ignoreUnknown=true)
public class PersonDTO {
  private String name;
  private String address;
  private String phone;
  private String other;
}

I am passing the following payload to an external API

{
    "name": "John",
    "phone": "123",
    "address": "abc"
}

This is throwing me 500 internal error:

HttpClientErrorException$NotFound: 404: "{<EOL> "status": "Error", <EOL> "message": "Error validating JSON. Error: - Invalid type Null, expected String."}"

If I comment out other property in DTO then I will successfully get 200 response. I thought @JsonIgnoreProperties annotation is supposed to ignore the properties that are not present but it seems that's not working.

CodePudding user response:

you are using lombok's @NoArgsConstructor and @AllArgsConstructor. So you have to use one or the other. If you don't want an all args constructor you'll have to implement your own.

@NoArgsConstructor
@Getter
@Setter
@Builder
@ToString
@JsonIgnoreProperties(ignoreUnknown=true)
public class PersonDTO {
  private String name;
  private String address;
  private String phone;
  private String other;

  public PersonDTO(String name, String address, String phone) {
    super(name, address, phone, "");
  }

  public PersonDTO(String name, String address, String phone, String other) {
    this.name = name;
    this.address = address;
    this.phone = phone;
    this.other = other
  }

}

Or if you have control over AND this is a spring boot app, you could try using required=false in your controller so you can continue to use an all arg constructor.

public PersonDTO getPerson(
      @PathVariable(value = "name") String name,
      @PathVariable(value = "address") String address
      @PathVariable(value = "phone") String phone
      @PathVariable(value = "other", required = false) String other) { 

 ....

}

CodePudding user response:

The error says that they can't parse Null into String. That's very interesting error and fooled me first. Your json object with other field null probably looks like this:

{
    "name": "John",
    "phone": "123",
    "address": "abc"
}

So somehow this API can't just wrap quotes around null and tells you it's not able to parse this.

Therefore I guess you need to set the value of other to an empty string:

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@ToString
@JsonIgnoreProperties(ignoreUnknown=true)
public class PersonDTO {
  private String name;
  private String address;
  private String phone;
  private String other = ""; //empty because external api can't handle null
}

CodePudding user response:

If attributes are nullable then you can use @JsonInclude(Include.NON_NULL). This will allow to set null value in the attributes. I guess, by default it doesn't allow null value.

CodePudding user response:

Adding @JsonInclude(JsonInclude.Include.NON_NULL) is the solution as you said in the comment. This annotation tells the serializer to ignore fields that are null. If you don't add this the payload will look like this:

{
    "name": "John",
    "phone": "123",
    "address": "abc",
    "other": null
}
  • Related