I'm making a Spring Boot application. I have an entity there:
@Entity
public class Employee {
@NotNull
private Category category;
// Education related fields
@NotNull
private Education education;
@NotBlank
private String eduName;
@NotNull
private LocalDate eduGraduationDate;
// other fields, getters, setters ...
}
As you can see, I have validation annotations there. But in my application I need to update the fields partially, e.g. client wants to update Education fields separately from Category field.
And the problem is that I cannot use PUT request to do that, because it will update whole object. If the Category field is actually null, and I want to update just the Education fields, I will get ConstraintViolationException, because the Category field is null. But it was null and I want it to be null further.
I can use PATCH request to do this:
@PatchMapping(path = "/{id}", consumes = "application/merge-patch+json")
public ResponseEntity<Employee> patchEmployee(@PathVariable Long id, @RequestBody JsonMergePatch jsonMergePatch) throws JsonPatchException, JsonProcessingException {
Employee employee = employeeDataService.findById(id).orElseThrow(() -> new ResourceNotFoundException("Employee not exist: id = " + id));
Employee employeePatched = applyPatchToEmployee(jsonMergePatch, employee);
return ResponseEntity.ok(employeeDataService.save(employeePatched));
}
private Employee applyPatchToEmployee(JsonMergePatch jsonMergePatch, Employee targetEmployee) throws JsonPatchException, JsonProcessingException {
JsonNode patched = jsonMergePatch.apply(objectMapper.convertValue(targetEmployee, JsonNode.class));
return objectMapper.treeToValue(patched, Employee.class);
}
But the question is: How can I validate my fields partially?
For example, if I send a PATCH request with body:
{
"education":"HIGHER",
"eduName":"MIT",
"eduGraduationDate":"2020-05-05"
}
How can I validate only this 3 fields? Not the whole Employee object? In this example, as I mentioned above, I want the Category field to be null and I don't want to validate it, if it is not included in the patch.
Maybe there are some better approaches to partially update entities, if so - which?
You can create a new DTO object with only fields you want to include for your PATCH call like,
EmployeePatchDto
public class EmployeePatchDto {
// Education related fields
@NotNull
private Education education;
@NotBlank
private String eduName;
@NotNull
private LocalDate eduGraduationDate;
// other fields, getters, setters ...
}
but now you'll still have to be sure that these validations are considered when you call the API.
Also, you can opt to validate your DTO class at controller method level by using @Valid like this,
public ResponseEntity<Employee> patchEmployee(@PathVariable Long id, @Valid @RequestBody EmployeePatchDto employeeDto) throws JsonPatchException, JsonProcessingException {
I'l leave this resource for you. Read this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With