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

AspectDetails
SpecificationJakarta Bean Validation 3.0
ImplementationHibernate Validator
Dependencyspring-boot-starter-validation
ScopeDTOs, 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)
Code
Loading 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)
Code
Loading syntax highlighter...

🔬 Deep Dive

Pattern 1: Built-in Constraints

JAVA(69 lines)
Code
Loading syntax highlighter...

Pattern 2: Nested Validation

JAVA(43 lines)
Code
Loading syntax highlighter...

Pattern 3: Custom Validators

JAVA(78 lines)
Code
Loading syntax highlighter...

Pattern 4: Cross-Field Validation

JAVA(90 lines)
Code
Loading syntax highlighter...

Pattern 5: Validation Groups

JAVA(58 lines)
Code
Loading syntax highlighter...

Pattern 6: Method Parameter Validation

JAVA(45 lines)
Code
Loading syntax highlighter...

Pattern 7: Conditional Validation

JAVA(69 lines)
Code
Loading syntax highlighter...

⚠️ Common Mistakes

Mistake 1: Forgetting @Valid for Nested Objects

JAVA(12 lines)
Code
Loading syntax highlighter...

Mistake 2: @Validated vs @Valid

JAVA(8 lines)
Code
Loading 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)
Code
Loading 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)
Code
Loading syntax highlighter...
The fix:
JAVA(13 lines)
Code
Loading syntax highlighter...
Same issue applies to collections:
JAVA(8 lines)
Code
Loading 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)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(18 lines)
Code
Loading syntax highlighter...

Exercise 2: Custom Password Validator

⭐⭐ Difficulty: Medium | ⏱️ Time: 20 minutes

Task: Create a custom password validator with configurable requirements.
JAVA(6 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(68 lines)
Code
Loading syntax highlighter...

Exercise 3: Cross-Field Validation

⭐⭐ Difficulty: Medium | ⏱️ Time: 20 minutes

Task: Create a class-level validator for password confirmation.
JAVA(4 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(66 lines)
Code
Loading syntax highlighter...

Exercise 4: Validation Groups

⭐⭐⭐ Difficulty: Medium-Hard | ⏱️ Time: 20 minutes

Task: Implement validation groups for create vs update operations.
JAVA(3 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(54 lines)
Code
Loading syntax highlighter...

Exercise 5: Method Parameter Validation

⭐⭐⭐⭐ Difficulty: Hard | ⏱️ Time: 25 minutes

Task: Enable validation on service method parameters.
JAVA(4 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(97 lines)
Code
Loading 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:
  1. Add @Validated to the class
  2. Add constraints to method parameters
  3. Spring AOP intercepts and validates
  4. ConstraintViolationException thrown on violation

📝 Summary

ConstraintUse For
@NotNull/@NotBlank/@NotEmptyRequired fields
@SizeLength limits
@Min/@Max/@PositiveNumeric bounds
@Email/@PatternFormat validation
@Past/@FutureDate constraints
@ValidNested validation
Custom validatorsBusiness rules
GroupsContext-specific validation

📅 Review Schedule for This Article

DayTaskTime
Day 1Review built-in constraints table5 min
Day 3Redo Exercise 1 (Basic Constraints)10 min
Day 7Answer interview questions without looking10 min
Day 14Redo Debug This (Silent Validation)15 min
Day 30Audit validation in one DTO in your codebase20 min

Next: [Part 18: Fluent Validation]