The validation process (in a nutshell)
- perform all field-level constraints' validations
- perform all method-level constraints' validations
- perform class-level constraints' validations
- perform cascade validations
- the validation routine will avoid infinite loops, keeping track of the validated object instances in the current validation process
- the validation routine won't execute the same validation more than once for the same validation constraint, keeping track if it matched on a previous group match.
Constraints semantics and constraint validator visibility
- If you apply a constraint to an object's field or property, you're applying a validation rule to that field (as part of a type), but the validation routine visibility is limited to only that object. You cannot access values of other fields of your object during the validation of the fields' constraints.
- If you apply a constraint to a type, the validation routine visibility will be able to apply class' invariants (if you've got any) and any other validation rule whose parameters may be whichever part (be it field or property) that make up your type.
Basically, you'll use field-level (resp: property-level) constraints when you want to apply the validation rule to that field (resp.: property) as part of a type. For example, a String id field may be length-bounded when part of a type, such as a Passport (A String isn't length-bounded by definition).
You'll use class-level constraints when you want to apply a validation rule to the state of a type as a whole. For example, if you define a Passport type you would apply a class level constraint to check that the id-field is coherent with the Country field.
That's why the validation routine starts from inside the bean and proceeds outwards: you would not apply validation rules to an entire class instance state if some of the class' fields were invalid.
Constraint design principles and a constraint domain
- discover that you need both a set of constraints for the Y domain and another set for X.id domain.
- need constraints for the Y type but it's not yours.