spring-framework
spring-framework copied to clipboard
Support Bean Validation in record constructors
Affects: 6.0.0-M1
I tried to add bean validation annotations on a record type, but it does not work as expected.
public record CreatePostCommand(@NotEmpty @Size(min = 5) String title, @NotEmpty String content) {
}
And write a controller test with MockMvc.
@Test
public void testCreatePost_validationFailed() throws Exception {
var id = UUID.randomUUID();
when(this.posts.save(any(Post.class)))
.thenReturn(Post.builder().id(id).title("test").build());
var data = new CreatePostCommand("a", "a");
this.rest.perform(post("/posts").content(objectMapper.writeValueAsBytes(data)).contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isUnprocessableEntity())
.andExpect(jsonPath("$.code", is("validation_failed")));
verify(this.posts, times(0)).save(any(Post.class));
verifyNoMoreInteractions(this.posts);
}
The test failed because the response always returned 201 status instead of the expected 422.
Related Articles
- https://www.morling.dev/blog/enforcing-java-record-invariants-with-bean-validation/
- https://blogs.oracle.com/javamagazine/post/diving-into-java-records-serialization-marshaling-and-bean-state-validation
As a side note, the above articles advocate using ByteBuddy to instrument the constructor invocation to automatically apply validation.
Oh, it is still lack of support in RC1. And as planed Spring 6 will be finally released in the next month, it means bean validation on Record will not work in Spring 6 GA?
Verified in Spring Boot 3.0, it seems Hibernate Validator 8.0 Final adds record support, check my updated example test: https://github.com/hantsy/spring6-sandbox/blob/master/boot/src/test/java/com/example/demo/web/PostControllerTest.java#L134
So I suppose this can be seen as a documentation ticket on our end now... documenting that Hibernate Validator 8.0 is needed for constraint annotations to be discovered on record types.
The documentation already refers to Hibernate Validator for specific usage of the API. Given that there's nothing specific to Spring here, I am going to close this.
Hi,
I am new with this Java Records, can someone help me with my issue?
I have 2 Records (PointsRedemptionV2Body & RedemptionItemBody) and I declared RedemptionItemBody as an array in the first record but the problem is the validation constraints from RedemptionItemBody are not working.
public record PointsRedemptionV2Body(
String orderReferenceNumber,
@NotNull
List<RedemptionItemBody> redemptionItemList) {
}
public record RedemptionItemBody(
@Min(value = 1L)
Integer redemptionItemNumber,
@Min(value = 1L)
Integer quantity,
@NotBlank
String awardId,
String catalogId,
@NotBlank
String shortDescription,
@NotBlank
String longDescription,
@NotBlank
String awardType,
@Min(value = 0L)
@MaxPointQuantity
Integer awardPointCost,
@NotNull
@Positive
Float companyCost
) {
}
@ybermejo I am afraid this is the wrong place to ask. We don’t use the issue tracker for questions, please use StackOverflow or the Hibernate Validator support forum.