Request DTO의 필드로 Enum 클래스를 사용하고자 한다.
위 코드를 살펴보자. Enum 타입의 필드 status
가 Enum 클래스이며, record 타입의 Request DTO 클래스 ReservationStatusUpdateReq
가 정의되어있다. 그리고 아래와 같이 @NotBlank
가 정상적으로 동작할 수 있게 RestController의 메서드에도 정상적으로 @Valid
를 사용했다.
그러나 웬걸, 실제로 API를 호출해보면 아래와 같이 validator
를 찾을 수 없다는 오류가 발생한다.
javax.validation.UnexpectedTypeException: HV000030:
No validator could be found for constraint 'javax.validation.constraints.NotBlank'
validating type 'com.prgms.allen.dining.domain.reservation.entity.ReservationStatus'. Check configuration for 'status'
결론부터 말하자면, @NotBlank
는 CharSequence
타입에만 사용할 수 있기 때문에 위의 Enum 타입의 필드에 사용한 경우는 오류가 발생한 것이다.
The annotated element must not be
null
and must contain at least one non-whitespace character. AcceptsCharSequence
공식문서에는 CharSequence
만 적용 가능하다고 명시되어있는데, 그렇다면 CharSequence
는 무엇인가?
인터페이스명(character + sequence)에서 짐작되듯이 char 값을 읽을 수 있는 시퀀스이다. 그리고 이 인터페이스는 다양한 종류의 char 시퀀스에 대해 균일한 읽기 전용 접근 권한을 제공한다. CharSequence 를 implements 하여 구현된 대표적인 클래스로는 String, SpannableStringBuilder, StringBuilder, StringBuffer 등이 있다.
출처: https://dudmy.net/android/2017/09/15/difference-char-string/
Request DTO 에 SpannableStringBuilder, StringBuilder, StringBuffer
타입은 잘 안쓰게 될 것 같으므로 현재로서는 @NotBlank
는 String 타입에만 사용가능하구나라고 이해해도 좋을 것 같다.
이쯤되면 자연스레 @NotBlank
의 친척 @NotNull
과 @NotEmpty
은 어떤 타입에만 사용할 수 있을지 궁금해진다. 그래서 준비했다.
The annotated element must not be
null
. Accepts any type.
@NotNull
은 무려 모든 타입에 사용 가능하다고 명시되어있다.
@NotEmpty
는 CharSequence
, Collection
, Map
, Array
타입이 가능하다고 명시되어있다. @NotBlank
보다 조금 여유로운 친구구나 하고 생각하면 될 듯하다.
Enum 을 Request DTO 의 필드로 쓰고 싶다면 @NotBlank
가 아닌 @NotNull
을 사용하자. (그것이 @NotBlank니까)
NotBlank (Java(TM) EE 8 Specification APIs)
NotEmpty (Java(TM) EE 8 Specification APIs)