Java

Fluent Validation

While Bean Validation works well for simple constraints, complex business rules often need programmatic validation. Fluent validation provides a readable, composable approach for complex validation scenarios with better error accumulation and conditional logic.

📋 At a Glance

AspectDetails
ApproachProgrammatic, builder-style validation
BenefitsReadable, composable, conditional logic
Best ForComplex business rules, cross-entity validation
LibrariesCustom, or inspired by FluentValidation (.NET)

🎯 What You'll Learn

  • Fluent validator implementation
  • Composable rules with chaining
  • Conditional validation based on context
  • Error accumulation vs fail-fast
  • Integration with Bean Validation

Production Story: The Complex Validation Rules

An insurance application had validation rules too complex for annotations:

JAVA(5 lines)
Code
Loading syntax highlighter...
The fix: Fluent validation:
JAVA(16 lines)
Code
Loading syntax highlighter...

🔬 Deep Dive

Pattern 1: Basic Fluent Validator

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

Pattern 2: Domain-Specific Validator

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

Pattern 3: Order Validator with Business Rules

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

Pattern 4: Validation Rules Builder

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

Pattern 5: Async Validation

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

Pattern 6: Integration with Bean Validation

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

⚠️ Common Mistakes

Mistake 1: Not Accumulating All Errors

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

Mistake 2: Validation with Side Effects

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

🐛 Debug This: The Premature Exit

A developer reports: "Our fluent validator only returns the first error even though we're supposed to accumulate all of them!"

JAVA(31 lines)
Code
Loading syntax highlighter...
Why does only one error get returned?

✅ Solution:
The bug is the multiple return errors; statements that exit early after each validation check. This is a fail-fast approach, but the intent was error accumulation.
The fix - remove early returns:
JAVA(26 lines)
Code
Loading syntax highlighter...
Even better - use fluent validator:
JAVA(9 lines)
Code
Loading syntax highlighter...
The lesson: Error accumulation requires checking all rules without early exits. Fluent validation naturally handles this pattern.

💻 Exercises

Exercise 1: Basic Fluent Validator

⭐ Difficulty: Easy | ⏱️ Time: 15 minutes

Task: Create a simple fluent validator with basic methods.
JAVA(5 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(60 lines)
Code
Loading syntax highlighter...

Exercise 2: Conditional Validation

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

Task: Add conditional validation to the fluent validator.
JAVA(9 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(33 lines)
Code
Loading syntax highlighter...

Exercise 3: Nested Object Validation

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

Task: Add support for validating nested objects and collections.
JAVA(3 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(63 lines)
Code
Loading syntax highlighter...

Exercise 4: Reusable Validation Rules

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

Task: Create composable, reusable validation rules.
JAVA(3 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(72 lines)
Code
Loading syntax highlighter...

Exercise 5: Validation with Result Type

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

Task: Integrate fluent validation with the Result pattern.
JAVA(4 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(108 lines)
Code
Loading syntax highlighter...

📝 Summary

ApproachUse When
Bean ValidationSimple constraints, standard validation
Fluent ValidationComplex rules, conditional logic, readability
CombinedBean for simple, fluent for business rules
Async ValidationDatabase checks, external service validation

📅 Review Schedule for This Article

DayTaskTime
Day 1Review fluent vs bean validation decision table5 min
Day 3Redo Exercise 1 (Basic Fluent Validator)15 min
Day 7Redo Exercise 3 (Nested Object Validation)20 min
Day 14Redo Debug This (Premature Exit)15 min
Day 30Identify complex validation in your codebase to refactor20 min

Next: [Part 19: Understanding Legacy Code]