@Validと@NotNull


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と長さ制限を設定する場合は、以下のように属性airtationを追加できます.

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.詳しい事項


検証ができない原因を知り、別の事実を知り整理した.@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