I've been trying for days to find a similar problem online and can't seem to find anything so I am asking my question here.
I have a controller:
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Validated
@RestController
@RequestMapping("/data")
public class TheController {
private final TheService theService;
@Autowired
public TheController(TheService theService) {
this.theService = theService;
}
@PostMapping(path = "/data", consumes = {MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.TEXT_PLAIN_VALUE})
public ResponseEntity<String> saveData(@Valid @RequestBody Data data) {
subscriptionDataFeedService.sendData(data.getDataList());
return ResponseEntity.ok()
.body("Data successful.");
}
}
I have the request body class:
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Data {
@NotEmpty(message = "Data list cannot be empty.")
@JsonProperty(value = "dataArray")
List<@Valid DataOne> dataList;
}
I have the DataOne class:
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class DataOne {
private @NotBlank String currency;
private @NotBlank String accountNumber;
private @NotBlank String finCode;
private String poNumber;
private @NotBlank String invoiceNumber;
private @NotNull Address billTo;
private @NotNull Address soldTo;
private @NotNull LocalDate invoiceDate;
private @NotBlank String billingPeriod;
private @NotNull LocalDate paymentDueDate;
private @NotNull BigDecimal amountDue;
@JsonProperty(value = "activitySummary")
private @NotNull List<@Valid ProductSummary> productSummaryList;
@JsonProperty(value = "accountSummary")
private @NotNull List<@Valid AccountSummary> accountSummaryList;
@JsonProperty(value = "transactions")
private @NotNull List<@Valid Transaction> transactionList;
private @NotNull PaymentByACH paymentByACH;
private @NotNull Address paymentByCheck;
private @NotNull CustomerServiceContact customerServiceContact;
}
And I will include the Address class:
import javax.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Address {
private @NotBlank String name;
private @NotBlank String address1;
private String address2;
private @NotBlank String city;
private @NotBlank String state;
private @NotBlank String postalCode;
}
I omitted some of the other classes because they aren't needed for my question.
So the problem I am having is that the @Valid annotation is able to validate everything except for the nested classes inside DataOne that aren't a list. In other words, it cannot validate the fields inside Address, PaymentByACH, etc. However, it is able to validate that those objects are @NotNull but is unable to validate the fields inside those classes.
The @Valid is unable to validate the name, address 1, city, etc fields inside of Address. Whenever I add an @Valid tag in front of the Address field inside DataOne I get an HV000028: Unexpected exception during isValid call exception.
How can I validate the nested fields inside of the Address object or any of the nested objects?
TL;DR: The objects that are a list, such as List<@Valid Transaction> transactionList; does validate the fields inside of Transaction but the code does not validate the fields inside of Address.
dataListfield with@Validas well. If you want to validate nested complex objects or collections those need to be annotated. Currently you annotated the generic type ofdataListand not the field. Hence it won't propagate. This ofcourse applies to the deeper nested fields as well. Also please remove the@Validatedfrom the controller level you don't need it and will only complicate things.