Validation: @Valid, @Validated, Bean Validation annotations. — Cracked Java
// Spring Framework & Spring Boot · Spring MVC & REST
MidCoding

Validation: @Valid, @Validated, Bean Validation annotations.

Spring delegates input validation to the Jakarta Bean Validation API (Hibernate Validator under the hood); @Valid and @Validated are the two triggers that turn it on. You annotate your DTO fields with constraints, mark the parameter to be validated, and Spring runs the validator before your method body executes.

The constraints live on the DTO

record CreateOrder(
    @NotNull Long customerId,
    @NotBlank @Size(max = 100) String description,
    @Positive BigDecimal amount,
    @Email String contactEmail,
    @Valid List<@NotNull LineItem> items   // cascades into each element
) {}

Common jakarta constraints: @NotNull, @NotBlank, @NotEmpty, @Size, @Min/@Max, @Positive, @Email, @Pattern, @Past/@Future.

@Valid — trigger validation on a parameter

jakarta.validation.@Valid on a @RequestBody (or @ModelAttribute) parameter tells Spring to validate the bound object. It also cascades into nested objects, which is why you put it on the items field above.

@PostMapping
OrderDto create(@Valid @RequestBody CreateOrder cmd) { ... }

On a @RequestBody, a constraint violation throws MethodArgumentNotValidException (→ 400 Bad Request). On an @ModelAttribute, you can instead accept a BindingResult immediately after the validated parameter to handle errors yourself.

@Validated — Spring's variant, with groups

org.springframework.validation.annotation.@Validated does the same but adds validation groups (validate different rules for create vs update), and at class level it enables method-level constraint validation on a bean's parameters/return values (throwing ConstraintViolationException).

@Validated
@Service
class OrderService {
    OrderDto find(@NotNull @Positive Long id) { ... } // validated on the bean
}

// Groups on a controller param:
OrderDto update(@Validated(OnUpdate.class) @RequestBody UpdateOrder cmd) { ... }

The rule of thumb

Use @Valid for ordinary request-body validation; reach for @Validated when you need groups or method-parameter validation on service beans. Note @Valid cannot carry groups — that's a @Validated-only feature.

Mark your status