Java
Bean Validation
Jakarta Bean Validation (formerly JSR-380) provides a declarative way to validate objects using annotations. This article covers built-in constraints, custom validators, groups, and integration with Spring Boot.
📋 At a Glance
| Aspect | Details |
|---|---|
| Specification | Jakarta Bean Validation 3.0 |
| Implementation | Hibernate Validator |
| Dependency | spring-boot-starter-validation |
| Scope | DTOs, entities, method parameters |
🎯 What You'll Learn
- Built-in constraints and when to use them
- Custom validators for business rules
- Validation groups for context-specific validation
- Cross-field validation for complex rules
- Spring integration with @Valid and @Validated
Production Story: The Manual Validation Nightmare
A registration service had validation scattered everywhere:
JAVA(13 lines)CodeLoading syntax highlighter...
Problems:
- Validation logic duplicated across endpoints
- Inconsistent error messages
- Easy to forget validation in new code
- Hard to test
- Business logic mixed with validation
The fix: Bean Validation annotations:
JAVA(20 lines)CodeLoading syntax highlighter...
🔬 Deep Dive
Pattern 1: Built-in Constraints
JAVA(69 lines)CodeLoading syntax highlighter...
Pattern 2: Nested Validation
JAVA(43 lines)CodeLoading syntax highlighter...
Pattern 3: Custom Validators
JAVA(78 lines)CodeLoading syntax highlighter...
Pattern 4: Cross-Field Validation
JAVA(90 lines)CodeLoading syntax highlighter...
Pattern 5: Validation Groups
JAVA(58 lines)CodeLoading syntax highlighter...
Pattern 6: Method Parameter Validation
JAVA(45 lines)CodeLoading syntax highlighter...
Pattern 7: Conditional Validation
JAVA(69 lines)CodeLoading syntax highlighter...
⚠️ Common Mistakes
Mistake 1: Forgetting @Valid for Nested Objects
JAVA(12 lines)CodeLoading syntax highlighter...
Mistake 2: @Validated vs @Valid
JAVA(8 lines)CodeLoading syntax highlighter...
🐛 Debug This: The Silent Validation
A developer reports: "Our nested object validation doesn't work! Invalid addresses are saved to the database."
JAVA(37 lines)CodeLoading syntax highlighter...
Why doesn't the address validation work?
✅ Solution:
The bug is a missing
@Valid annotation on the nested shippingAddress field. Bean Validation does NOT automatically cascade to nested objects - you must explicitly tell it to validate nested objects with @Valid.JAVA(2 lines)CodeLoading syntax highlighter...
The fix:
JAVA(13 lines)CodeLoading syntax highlighter...
Same issue applies to collections:
JAVA(8 lines)CodeLoading syntax highlighter...
The lesson: Always add
@Valid to fields that contain nested objects or collections that need validation. Bean Validation only checks the immediate field by default.💻 Exercises
Exercise 1: Basic Constraints
⭐ Difficulty: Easy | ⏱️ Time: 10 minutes
Task: Add validation constraints to this DTO.
JAVA(12 lines)CodeLoading syntax highlighter...
✅ Solution:
JAVA(18 lines)CodeLoading syntax highlighter...
Exercise 2: Custom Password Validator
⭐⭐ Difficulty: Medium | ⏱️ Time: 20 minutes
Task: Create a custom password validator with configurable requirements.
JAVA(6 lines)CodeLoading syntax highlighter...
✅ Solution:
JAVA(68 lines)CodeLoading syntax highlighter...
Exercise 3: Cross-Field Validation
⭐⭐ Difficulty: Medium | ⏱️ Time: 20 minutes
Task: Create a class-level validator for password confirmation.
JAVA(4 lines)CodeLoading syntax highlighter...
✅ Solution:
JAVA(66 lines)CodeLoading syntax highlighter...
Exercise 4: Validation Groups
⭐⭐⭐ Difficulty: Medium-Hard | ⏱️ Time: 20 minutes
Task: Implement validation groups for create vs update operations.
JAVA(3 lines)CodeLoading syntax highlighter...
✅ Solution:
JAVA(54 lines)CodeLoading syntax highlighter...
Exercise 5: Method Parameter Validation
⭐⭐⭐⭐ Difficulty: Hard | ⏱️ Time: 25 minutes
Task: Enable validation on service method parameters.
JAVA(4 lines)CodeLoading syntax highlighter...
✅ Solution:
JAVA(97 lines)CodeLoading syntax highlighter...
🎤 Interview Questions
Q1: Difference between @NotNull, @NotEmpty, @NotBlank?
Answer:
@NotNull: Not null, but can be empty string or empty collection@NotEmpty: Not null AND not empty (size > 0), for String/Collection/Map/Array@NotBlank: Not null AND not empty AND not just whitespace, only for String
Q2: How to validate method parameters in a service?
Answer:
- Add
@Validatedto the class - Add constraints to method parameters
- Spring AOP intercepts and validates
ConstraintViolationExceptionthrown on violation
📝 Summary
| Constraint | Use For |
|---|---|
| @NotNull/@NotBlank/@NotEmpty | Required fields |
| @Size | Length limits |
| @Min/@Max/@Positive | Numeric bounds |
| @Email/@Pattern | Format validation |
| @Past/@Future | Date constraints |
| @Valid | Nested validation |
| Custom validators | Business rules |
| Groups | Context-specific validation |
📅 Review Schedule for This Article
| Day | Task | Time |
|---|---|---|
| Day 1 | Review built-in constraints table | 5 min |
| Day 3 | Redo Exercise 1 (Basic Constraints) | 10 min |
| Day 7 | Answer interview questions without looking | 10 min |
| Day 14 | Redo Debug This (Silent Validation) | 15 min |
| Day 30 | Audit validation in one DTO in your codebase | 20 min |
Next: [Part 18: Fluent Validation]