spring-framework icon indicating copy to clipboard operation
spring-framework copied to clipboard

Support Bean Validation in record constructors

Open hantsy opened this issue 3 years ago • 2 comments

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.

hantsy avatar Jan 01 '22 05:01 hantsy

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.

sbrannen avatar Jan 03 '22 13:01 sbrannen

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?

hantsy avatar Oct 15 '22 10:10 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

hantsy avatar Dec 03 '22 15:12 hantsy

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.

jhoeller avatar Jul 12 '23 19:07 jhoeller

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.

snicoll avatar Oct 24 '23 13:10 snicoll

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 avatar Nov 06 '23 18:11 ybermejo

@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.

snicoll avatar Nov 07 '23 07:11 snicoll