I have a bean that has a lot of fields annotated with JSR-303 validation annotations. There is a new requirement now that one of the fields is mandatory, but only in certain conditions.
I looked around and have found what I needed, validation groups.
This is what I have now:
public interface ValidatedOnCreationOnly { } @NotNull(groups = ValidatedOnCreationOnly.class) private String employerId; @Length(max = 255) @NotNull private String firstName; @Length(max = 255) @NotNull private String lastName;
However, when I run this validation in a unit test:
@Test public void testEmployerIdCanOnlyBeSetWhenCreating() { EmployeeDTO dto = new EmployeeDTO(); ValidatorFactory vf = Validation.buildDefaultValidatorFactory(); Set<ConstraintViolation<EmployeeDTO>> violations = vf.getValidator().validate(dto, EmployeeDTO.ValidatedOnCreationOnly.class); assertEquals(violations.size(), 3); }
It turns out that all of the non-group annotated validations are ignored and I get only 1 violation.
I can understand this behaviour but I would like to know if there is a way I can make the group include all non-annotated parameters as well. If not I'd have to do something like this:
public interface AlwaysValidated { } public interface ValidatedOnCreationOnly extends AlwaysValidated { } @NotNull(groups = ValidatedOnCreationOnly.class) private String employerId; @Length(max = 255, groups = AlwaysValidated.class) @NotNull(groups = AlwaysValidated.class) private String firstName; @Length(max = 255, groups = AlwaysValidated.class) @NotNull(groups = AlwaysValidated.class) private String lastName;
The real class I'm working with has a lot more fields (about 20), so this method turns what was a clear way of indicating the validations into a big mess.
Can anyone tell me if there is a better way? Maybe something like:
vf.getValidator().validate(dto, EmployeeDTO.ValidatedOnCreationOnly.class, NonGroupSpecific.class);
I'm using this in a spring project so if spring has another way I'll be glad to know.
1 Overview of the JSR-303 Bean Validation API. JSR-303 standardizes validation constraint declaration and metadata for the Java platform. Using this API, you annotate domain model properties with declarative validation constraints and the runtime enforces them.
Validation groups allow you to organize validation controls on a page as a set. Each validation group can perform validation independently from other validation groups on the page. You create a validation group by setting the ValidationGroup property to the same name (a string) for all the controls you want to group.
The @Valid annotation ensures the validation of the whole object. Importantly, it performs the validation of the whole object graph. However, this creates issues for scenarios needing only partial validation. On the other hand, we can use @Validated for group validation, including the above partial validation.
Group constraints are optional linear constraints that group assets together and enforce bounds on the group weights (see Group Constraints).
There is a Default
group in javax.validation.groups.Default
, which represents the default Bean Validation group. Unless a list of groups is explicitly defined:
Default
groupDefault
groupYou could extends this group:
public interface ValidatedOnCreationOnly extends Default {}
just wanted to add more:
if you're using spring framework you can use org.springframework.validation.Validator
@Autowired private Validator validator;
and to perform validation manually:
validator.validate(myObject, ValidationErrorsToException.getInstance());
and in controller:
@RequestMapping(method = RequestMethod.POST) public Callable<ResultObject> post(@RequestBody @Validated(MyObject.CustomGroup.class) MyObject request) { // logic }
although in this way extending from javax.validation.groups.Default
won't work so you have to include Default.class
in groups:
class MyObject { @NotNull(groups = {Default.class, CustomGroup.class}) private String id; public interface CustomGroup extends Default {} }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With