Validation
About
Jakarta Validation (formerly Bean Validation) is a Java specification that allows us to declaratively define constraints on object models (beans) and validate them at runtime. It is defined by the Jakarta EE platform and comes under the package jakarta.validation
.
Originally part of the javax.validation
package, it was renamed as part of the Jakarta EE transition. Jakarta Validation can be used in any Java SE application.
Primary Use Cases
Validating user input (e.g., REST API requests)
Validating data transfer objects (DTOs)
Validating method parameters and return values
Applying cross-field and class-level validations
Important Terminology
Constraint
A rule that must be satisfied by a field or object
Constraint Validator
A class that checks whether a given constraint is satisfied
Constraint Violation
A validation failure message returned after validation
Metadata
The annotations and their parameters defined on fields/methods
ConstraintDescriptor
Runtime metadata for each constraint
Validator
Main interface to perform validation operations
@Valid
Annotation to enable recursive/nested validation
Group
Allows validating only a specific subset of constraints
Example: Basic Flow
Execution Steps (Internal):
At runtime,
Validator
reflects on the classUser
.For each field:
It checks what constraint annotations are present.
Each constraint is mapped to a
ConstraintValidator
implementation.
The field value is extracted (e.g.,
username = "ab"
).The validator (
SizeValidator
) is executed.If validation fails, it creates a
ConstraintViolation
with metadata like:invalid value
message
path
constraint type
The process is repeated for all constraints and fields.
The result is a
Set<ConstraintViolation<T>>
.
Do we have to check violations manually?
Yes, if we're using pure Java SE (no Spring, no Jakarta EE web framework), we must manually invoke the validator as shown above.
The framework does not validate automatically when we call
setUsername(...)
. Constraints are only applied when we callvalidator.validate(obj)
or via framework support.
Will Java do this automatically?
No. Not in Java SE.
Yes. If we use a framework like Spring Boot or Jakarta REST with annotations like
@Valid
, then the framework will do this automatically.
Validator Interface and ConstraintValidator
jakarta.validation.Validator
: Entry point to the validation engine.jakarta.validation.ConstraintValidator<A, T>
: Generic interface to implement custom validation logic.
How a Validator Works Internally
Let’s walk through the execution using @Email
.
The validation engine sees
@Email
.The
EmailValidator
class is registered as the implementation ofConstraintValidator<Email, String>
.During validation:
The
initialize()
method ofEmailValidator
is called (if needed).Then, the
isValid(value, context)
method is called.Inside
isValid
, logic like regex matching or domain checking is applied.
Code behind the scenes:
Constraint Declaration and Meta-Annotations
Every annotation like @Email
, @NotNull
is:
Annotated with
@Constraint(validatedBy = X.class)
Annotated with
@Target
,@Retention
Must define
message
,groups
,payload
Example: Behind @NotNull
How Recursive / Nested Validation Works (@Valid
)
@Valid
)Scenario:
What happens when we validate Order
?
Order
?When
Validator.validate(order)
is called:It sees
@Valid
oncustomer
field.It recursively calls
validate(customer)
.Then applies
@NotNull
and@Email
on theCustomer
fields.
If
@Valid
is not present, the nested object is skipped.
Validation Groups
We use Validation Groups if we want different validation rules in different scenarios (e.g., Create vs Update).
Step 1: Define groups
Step 2: Use in model
Step 3: Validate by group
Last updated
Was this helpful?