본문으로 건너뛰기
Advertisement

6.4 Validation Groups (검증 그룹)

등록(생성) 시와 수정 시에 서로 다른 검증 규칙을 적용하고 싶을 때 Validation Groups를 사용합니다. 예: 등록 시에는 id 없음, 수정 시에는 id 필수.

작성 기준: Bean Validation (JSR 380), Spring

1. 그룹 인터페이스 정의

public interface CreateGroup {}
public interface UpdateGroup {}
  • 빈 인터페이스만 두고 마커로 사용합니다.

2. 엔티티/DTO에 그룹 지정

@Getter
@Setter
public class MemberDto {

@NotNull(groups = UpdateGroup.class)
private Long id;

@NotBlank(groups = { CreateGroup.class, UpdateGroup.class })
private String name;

@NotBlank(groups = CreateGroup.class)
@Size(min = 8, groups = CreateGroup.class)
private String password;

@Email(groups = { CreateGroup.class, UpdateGroup.class })
private String email;
}
  • groups: 해당 제약이 적용되는 그룹. 여러 그룹에 같은 제약을 걸 수 있습니다.
  • UpdateGroup일 때만 id 필수, CreateGroup일 때만 password 필수·길이 검사 등으로 나눌 수 있습니다.

3. 컨트롤러에서 @Validated에 그룹 지정

@PostMapping
public ResponseEntity<MemberDto> create(@Validated(CreateGroup.class) @RequestBody MemberDto dto) {
return ResponseEntity.ok(memberService.create(dto));
}

@PutMapping("/{id}")
public ResponseEntity<MemberDto> update(
@PathVariable Long id,
@Validated(UpdateGroup.class) @RequestBody MemberDto dto) {
dto.setId(id);
return ResponseEntity.ok(memberService.update(dto));
}
  • @Validated(그룹.class) 로 “이 요청에서는 이 그룹만 검증”하도록 지정합니다.
  • @Valid 는 그룹을 지정하지 않으며, groups가 없는 제약만 동작합니다.

4. 그룹 순서 (GroupSequence)

그룹을 순서대로 검증하려면 @GroupSequence를 사용합니다.

@GroupSequence({ FirstCheck.class, SecondCheck.class, MemberDto.class })
public interface OrderedChecks {}

public interface FirstCheck {}
public interface SecondCheck {}
  • FirstCheck 실패 시 SecondCheck는 실행되지 않습니다.

등록/수정 DTO를 분리해 CreateRequest, UpdateRequest로 두고 각각 다른 검증을 거는 방식도 많이 씁니다. 그룹은 “한 DTO에 여러 용도”를 둘 때 유용합니다.


실전 고수 팁 — JPA Entity와 DTO 분리 원칙

많은 주니어 개발자들이 JPA @Entity 클래스 내부에 @NotBlank, @Size 같은 Validation 애너테이션을 덕지덕지 붙입니다. 이는 매우 나쁜 안티 패턴입니다.

왜 Entity에 Validation을 넣으면 안 되는가?

  1. 화면마다 유효성 조건이 다름: 유저 "가입" 시에는 비밀번호가 필수(@NotBlank)지만, 유저 "정보 수정" 시에는 비밀번호가 빈 값일 수도 있습니다. 하나의 Entity로 두 가지 화면의 유효성을 모두 맞출 수 없습니다.
  2. DB 제약조건과의 혼동: @Column(nullable = false)는 데이터베이스 스키마와 관련된 롬복/JPA 스펙이고, @NotNull은 애플리케이션 계층의 검증기능입니다. 이를 섞어 쓰면 유지보수가 어려워집니다.

올바른 실무 패턴

반드시 API 요청 모델(Request DTO)을 화면/기능별로 분리하고, Validation 애너테이션은 오직 DTO 컨트롤러 파라미터 계층에서만 수행해야 합니다. Entity는 순수하게 도메인 로직과 DB 매핑만 담당해야 합니다.

Advertisement