Enum 타입은 @NotBlank를 사용할 수 없다.

해로(haero77)·2023년 1월 26일
0

트러블 슈팅

목록 보기
1/6

발단

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'

원인

결론부터 말하자면, @NotBlankCharSequence 타입에만 사용할 수 있기 때문에 위의 Enum 타입의 필드에 사용한 경우는 오류가 발생한 것이다.

The annotated element must not be null  and must contain at least one non-whitespace character. Accepts CharSequence

공식문서에는 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 타입에만 사용가능하구나라고 이해해도 좋을 것 같다.


@NotNull 과 @NotEmpty

이쯤되면 자연스레 @NotBlank 의 친척 @NotNull@NotEmpty 은 어떤 타입에만 사용할 수 있을지 궁금해진다. 그래서 준비했다.


@NotNull

The annotated element must not be null . Accepts any type.

@NotNull 은 무려 모든 타입에 사용 가능하다고 명시되어있다.


@NotEmpty

@NotEmptyCharSequence , Collection , Map , Array 타입이 가능하다고 명시되어있다. @NotBlank 보다 조금 여유로운 친구구나 하고 생각하면 될 듯하다.


결론

Enum 을 Request DTO 의 필드로 쓰고 싶다면 @NotBlank 가 아닌 @NotNull 을 사용하자. (그것이 @NotBlank니까)

참고

NotBlank (Java(TM) EE 8 Specification APIs)

NotEmpty (Java(TM) EE 8 Specification APIs)

NotNull (Java(TM) EE 8 Specification APIs)

CharSequence와 String의 차이 (feat. StringSpannableBuilder)

profile
Every Run, Learn Counts.

0개의 댓글