Skip to main content
Advertisement

6.4 Validation Groups

Use Validation Groups when create and update need different rules (e.g. no id on create, required id on update).

Reference: Bean Validation (JSR 380), Spring

1. Group Interfaces

public interface CreateGroup {}
public interface UpdateGroup {}
  • These are empty interfaces used as markers.

2. Assign Groups on Entity/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: Groups the constraint applies to. The same constraint can be applied to multiple groups.
  • id required only for UpdateGroup, password required only for CreateGroup, etc.

3. @Validated(Group.class) in Controller

@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(Group.class) specifies "validate only this group for this request".
  • @Valid does not specify a group and only activates constraints with no groups specified.

4. GroupSequence

Validate groups in order using @GroupSequence.

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

public interface FirstCheck {}
public interface SecondCheck {}
  • If FirstCheck fails, SecondCheck is not executed.

tip

Alternatively, separate DTOs into CreateRequest and UpdateRequest with different validations for each. Groups are most useful when "one DTO serves multiple purposes".


Pro Tips — Separating JPA Entities and DTOs

Many junior developers carelessly attach Validation annotations like @NotBlank and @Size directly inside their JPA @Entity classes. This is a severe anti-pattern.

Why you shouldn't put Validation on Entities

  1. Validation constraints vary by screen: During User "Registration", a password is required (@NotBlank). However, during User "Profile Update", the password field might be intentionally omitted. A single Entity cannot logically satisfy both scenarios simultaneously.
  2. Confusion with DB Constraints: @Column(nullable = false) is a JPA specification strictly bound to the DB schema, whereas @NotNull is an application-tier HTTP payload validator. Mixing them obfuscates the architectural layers.

The Correct Production Pattern

You MUST absolutely separate Request Payload Models (DTOs) per functional scenario. Validation annotations belong SOLELY on the DTO layer during Controller parameter binding. The Entity class should remain pristine, dedicated purely to Domain logic and database metadata mappings.

Advertisement