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.
idrequired only for UpdateGroup,passwordrequired 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
FirstCheckfails,SecondCheckis not executed.
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
- 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. - Confusion with DB Constraints:
@Column(nullable = false)is a JPA specification strictly bound to the DB schema, whereas@NotNullis 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.