The same object often needs different rules for different operations: an id is required on update but generated on create, and a field may be optional in a draft but required on submit. Validation groups let you apply a subset of constraints per operation instead of duplicating the class.
Before you start
You should be comfortable with bean validation annotations. This article covers groups and ordering.
Step-by-step walkthrough
Step 1: Define marker interfaces for groups
An empty interface such as OnCreate or OnUpdate is a group marker. Annotate each constraint with the group it belongs to, so @NotNull(groups = OnUpdate.class) applies only when that group is validated.
Step 2: Validate the group you need
@Validated(OnCreate.class) on a controller method (or validator.validate(obj, OnCreate.class)) runs only the constraints in that group. The default group applies when no group is specified, so constraints without a group always run unless you move them.
Step 3: Sequence with group order
@GroupSequence orders groups so the next runs only if the previous passes, which avoids reporting a missing id before checking a basic field. This keeps error messages focused and sensible for the user.
Worked scenario
Create and update apply different constraints.
interface OnCreate {}
interface OnUpdate {}
class UserRequest {
@Null(groups = OnCreate.class)
@NotNull(groups = OnUpdate.class)
private Long id;
@NotBlank(groups = {OnCreate.class, OnUpdate.class})
private String name;
}Walk through the example
On create, id must be null (the server assigns it); on update, it must be present. name is required in both. Validating with OnCreate checks the create rules, and OnUpdate checks the update rules, so one class serves both operations without duplication.
Common mistake
Using one set of rules for all operations, which forces awkward optional fields or rejects valid input. Another is forgetting that a constraint with no group runs in the default group and may not fire when validating a custom group.
Verify the behavior
Validate with OnCreate and confirm id must be null; validate with OnUpdate and confirm it must be present. Check that name is required in both. Add a group sequence and confirm validation stops early on the first failing group.
Interview exercise
Why do constraints in a custom group not run when validating the default group?
Answer and reasoning
Because groups partition constraints: validating the default group runs, and only the constraints assigned to it. A constraint explicitly assigned to OnCreate belongs to that group, not the default, so validating the default does not trigger it. This separation is what allows different rules per operation.
Continue learning
Compare request checks in Request validation and error shape in Problem details. Read the Jakarta bean validation groups documentation and try the Spring Boot interview questions.