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.
Comment From: sbrannen
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.
Comment From: hantsy
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?
Comment From: hantsy
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
Comment From: jhoeller
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.
Comment From: snicoll
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.
Comment From: ybermejo
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
) {
}
Comment From: snicoll
@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.