Missing Cascading Bean Validation
ID |
java.bean_validation_jsr_380_properly |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
reliability, validation |
Description
Reports a field whose declared type is itself a project bean carrying Bean Validation
constraints (@NotNull, @Size, and the rest of JSR 380) but the field itself is not annotated
@Valid. Only fields whose type is proven, project-wide, to declare at least one constraint of
its own are reported — a plain class-typed field with nothing to cascade into is not.
Two further conditions keep the finding to fields where a constraint really is dropped. The
enclosing class must itself declare at least one constraint, the local evidence that a validator
ever visits it: a JUnit fixture or a Spring @Component holding a bean-typed field is never
validated, so a missing @Valid there costs nothing. And an enum-typed field is skipped — @Valid does not cascade into an enum constant, whatever constraints the enum’s own fields carry.
A bean that composes other beans without declaring a single constraint of its own is a known false negative: nothing in the file says it is ever validated.
Rationale
@NotNull, @Size and the other JSR 380 constraint annotations are only evaluated on the object
the validator was directly asked to validate. A field that holds another bean is not
automatically walked into: without @Valid on that field, every constraint declared on the
nested bean’s own fields is silently skipped, no matter how the containing object is validated.
public class ShippingAddress {
@NotNull
private String street;
}
public class Order {
@NotNull
private String reference; // the constraint that shows Order is validated
private ShippingAddress address; // FLAW -- ShippingAddress's @NotNull never runs
}