Unravel โบ Java concepts โบ Spring and Boot
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
A bouncer at the door with a checklist: age over 18, name not empty, ticket valid.
- 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.
- 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@Validated on a class enables the same checks on method parameters of any Spring bean, and on @RequestParam and @PathVariable values
- 4Nested objects are only checked when the field holding them is also marked @Valid; otherwise the inner constraints are silently ignored
- Validation checks the shape of one object, not business rules that need a database ("is this email already registered?")
- @NotNull only rejects null, @NotEmpty also rejects empty collections and strings, and @NotBlank also rejects strings of only spaces
- Spring uses a Jakarta Bean Validation provider, usually Hibernate Validator
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);}- line 2 uses NotBlank, the core of Bean validation (@Valid)
- line 3 uses Positive, the core of Bean validation (@Valid)
- line 4 uses Email, the core of Bean validation (@Valid)
- 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
@NotNullwhere@NotBlankwas meant. - Expecting nested objects to be validated without
@Validon 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:
- Annotations:
@Valid@Validated@NotNull@NotBlank@NotEmpty@Size@Min@Max@Email@Positive@PositiveOrZero@Past@Future@DecimalMinand 1 more - Types:
ValidatorConstraintViolationBindingResultMethodArgumentNotValidException
Part of a learning path
- How a Spring request really works ยท previous: Spring REST controllers ยท next: Spring Security basics
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.