BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ Spring and Boot

Spring

Bean validation (@Valid)

Bean validation lets you declare rules on fields (@NotBlank, @Size(max = 50), @Email) and have the framework check them.

Learn these first

At a glance

Mental model

A bouncer at the door with a checklist: age over 18, name not empty, ticket valid.

What happens, in order
  1. 1Constraints are annotations on the fields of a class: @NotBlank String name; @Min(18) int age; @Email String email;Each has a default message and can take a custom one.
  2. 2Adding @Valid to a parameter, as in create(@Valid @RequestBody OrderRequest req), makes Spring run the validator after the JSON is parsedIf any rule fails, it throws MethodArgumentNotValidException, which becomes an HTTP 400 with the failed fields.
  3. 3@Validated on a class enables the same checks on method parameters of any Spring bean, and on @RequestParam and @PathVariable values
  4. 4Nested objects are only checked when the field holding them is also marked @Valid; otherwise the inner constraints are silently ignored
Remember
Watch out
Forgetting @Valid, so no check happens and nothing warns youUsing @NotNull where @NotBlank was meantExpecting nested objects to be validated without @Valid on the fieldPutting database-dependent rules into constraints
Example (highlighted lines explain it)
public record OrderRequest(    @NotBlank @Size(max = 40) String customerId,    @Positive int quantity,    @Email String contactEmail) {}@PostMapping("/orders")public OrderDto create(@Valid @RequestBody OrderRequest req) {    return service.create(req);}
  1. line 2 uses NotBlank, the core of Bean validation (@Valid)
  2. line 3 uses Positive, the core of Bean validation (@Valid)
  3. line 4 uses Email, the core of Bean validation (@Valid)
  4. line 7 uses Valid, the core of Bean validation (@Valid)
Read the full explanation (about 2 min)

Bean validation lets you declare rules on fields (@NotBlank, @Size(max = 50), @Email) and have the framework check them. In a Spring controller, @Valid on a request body rejects bad input with a 400 before your code runs.

A mental model

A bouncer at the door with a checklist: age over 18, name not empty, ticket valid. Anyone who fails never gets inside, so the people working inside do not have to re-check at every table.

How it works

Constraints are annotations on the fields of a class: @NotBlank String name; @Min(18) int age; @Email String email;. Each has a default message and can take a custom one.

Adding @Valid to a parameter, as in create(@Valid @RequestBody OrderRequest req), makes Spring run the validator after the JSON is parsed. If any rule fails, it throws MethodArgumentNotValidException, which becomes an HTTP 400 with the failed fields.

@Validated on a class enables the same checks on method parameters of any Spring bean, and on @RequestParam and @PathVariable values.

Nested objects are only checked when the field holding them is also marked @Valid; otherwise the inner constraints are silently ignored.

Going deeper

Validation checks the shape of one object, not business rules that need a database ("is this email already registered?"). Keep those in the service layer, where a failure can be reported with the right meaning.

@NotNull only rejects null, @NotEmpty also rejects empty collections and strings, and @NotBlank also rejects strings of only spaces. Choosing the wrong one is the most common mistake.

Customise the error response with an @ExceptionHandler or @RestControllerAdvice so clients get a consistent JSON body listing field names and messages instead of the default.

Validate at the edge, but do not trust the edge alone: a service called from a scheduled job or a message listener never passed through the controller, so it may need its own checks.

Under the hood

Spring uses a Jakarta Bean Validation provider, usually Hibernate Validator. The constraint annotations carry a validator class; at run time the provider walks the object graph, calls each validator and collects ConstraintViolations. Spring MVC invokes it from the argument resolver that reads the request body.

Common mistakes

  • Forgetting @Valid, so no check happens and nothing warns you.
  • Using @NotNull where @NotBlank was meant.
  • Expecting nested objects to be validated without @Valid on the field.
  • Putting database-dependent rules into constraints.

How Unravel recognises it

When you paste code, Unravel looks for these signs of bean validation (@valid). Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is Bean validation (@Valid)?

Bean validation lets you declare rules on fields (@NotBlank, @Size(max = 50), @Email) and have the framework check them. In a Spring controller, @Valid on a request body rejects bad input with a 400 before your code runs.

What are the most common mistakes with Bean validation (@Valid)?

Forgetting @Valid, so no check happens and nothing warns you. Using @NotNull where @NotBlank was meant. Expecting nested objects to be validated without @Valid on the field. Putting database-dependent rules into constraints.

How can I see Bean validation (@Valid) in real code?

Paste your own Java into Unravel and it will point out where bean validation (@valid) appears, explain how it works at the detail level you choose, and draw the flow of the code around it.