@Valid와 @NotNull

지니·2021년 10월 3일
0

대학생의 일기

목록 보기
12/17

1. @Valid

@Valid 어노테이션이란?

@Valid는 제약조건을 달아놓은 속성에 대해 유효성 검사를 하는 어노테이션이다.

개인적으로 Controller 클래스 내의 메소드에서 DTO를 인자로 받을 때 아래와 같이 적용하곤 하였다.

ex)

UserDto.java

// getter, setter 생략

class UserDto {
    Long id;
    String name;
}

UserController.java

...
class UserController {
    ...
    public Response<String> create(@RequestBody @Valid UserDto user) {
    	...
    }
}

하지만, 여기서 지금까지 몰랐던 사실이 있었다.




@Valid가 적용이 안되는 경우

JPA를 사용하면서 @Embedded와 @Embedable을 사용할 일이 생긴다.


ex)

UserDto.java

// getter, setter 생략

class UserDto {
    Long id;
    String name;
    @Embedded
    Address address;
}

Address

// getter, setter 생략

@Embeddable
class Address {
    Long id;
    String city;
    ...
}


이 상태에서 Address의 city 속성에 @NotBlank와 길이 제한을 두고 싶다면 아래와 같이 속성에 어노테이션을 달아줄 수 있다.

Address.java

// getter, setter 생략

@Embeddable
class Address {
    Long id;
    
    @NotBlank
    @Size(min = 1, max = 20) 
    String city;
    ...
}

이렇게 적용하면 Address 객체의 city에 대해서도 유효성을 검사해줄 것이라고 생각했는데 그렇지 않다. UserController의 인자로 받는 UserDto에 대한 @Valid의 입장에서 보았을 때, Address 자체를 속성으로 보는 것 같다.

즉,

UserDto.java

// getter, setter 생략

class UserDto {
    Long id;
    String name;
    
    @NotNull
    @Embedded
    Address address;
}

이렇게 써주게 되면 address 속성 자체가 없는 경우에는 예외가 발생한다는 뜻이다.


그렇다면, Address 내의 속성들에 대해서는 어떻게 검증을 하면 될지 생각해보자.


간단하다.

// getter, setter 생략

class UserDto {
    Long id;
    String name;
    
    @Valid
    @NotNull
    @Embedded
    Address address;
}

address 위에 @Valid를 붙여주면 된다. 그렇다면 Access 객체의 속성에 대해서도 유효성 검사를 하겠다는 뜻이 된다.




2. 추가로 알게 된 사항

유효성 검사가 안되는 이유에 대해서 알아보다가, 또 다른 사실을 알게 되어 정리하게 되었다. primitive type에 @NotNull을 적용하였을 때, 적용이 안된다는 글을 우연히 접하게 되었다.


UserDto.java

// getter, setter 생략

class UserDto {
    Long id;
    String name;
    
    @NotNull
    int age;
}

적용이 안되는 이유는, primitive type인 int는 자동으로 0으로 초기화 되므로, @NotNull에 걸리지 않게 되기 때문이다. 이럴 때는, 아래와 같이 적용하면 된다.


UserDto.java

// getter, setter 생략

class UserDto {
    Long id;
    String name;
    
    @NotNull
    Integer age;
}




Reference
Spring Boot not validating Embedded object on Entity

profile
Coding Duck

1개의 댓글

comment-user-thumbnail
2일 전

보통 Entity에 @NotNull 등의 어노테이션을 달아 검증을 시도하는데,
맨 위 코드처럼 DTO 검증을 시도하려면, 해당 Entity의 DTO 또한 @NotNull 등의 어노테이션을 달아줘야 하나요?

답글 달기