I'm trying to do a nested validation in my Spring application.
public class Parent{
public interface MyGroup{}
@NotNull(groups = MyGroup.class)
private Child child;
// getters and setters omited
}
public class Child{
public interface OptionalGroup {}
@NotBlank(groups = OptionalGroup.class)
private String aField;
}
I already looked at @Valid from javax.validation package but it doesn't support group. I also checked @Validated annotation from spring but I can't applied it on a field.
I want to do something like :
public class Parent{
public interface MyGroup{}
@NotNull(groups = MyGroup.class)
@CascadeValidate(groups = MyGroup.class, cascadeGroups = OptionalGroup.class)
// 'groups' correspond to parent group and 'cascadeGroups' to a group that needs to be apply to the Child field.
private Child child;
}
And then I can pragmatically do wherever I want:
@Inject SmartValidator validator;
public void validationMethod(Parent parent, boolean condition) throws ValidationException {
if(condition){
MapBindingResult errors= new MapBindingResult(new HashMap<>(), target.getClass().getSimpleName());
validator.validate(parent, errors, Parent.MyGroup.class); // validate all constraints associated to MyGroup
if(errors.hasErrors()) throw new ValidationException(errors); // A custom exception
}
}
Any ideas how to do that?
Thanks a lot
I finally found the solution. Actually I misunderstood what @Valid
was made for.
The key is to declare same group for Parent and child attribute.
Solution :
public class Parent{
public interface MyGroup{}
@NotNull(groups = MyGroup.class)
@Valid // This annotation will launch nested validation
private Child child;
// getters and setters omited
}
public class Child{
@NotBlank(groups = Parent.MyGroup.class) // Declare same group
private String aField;
}
In this case, when I do :
@Inject SmartValidator validator;
public void validationMethod(Parent parent, boolean condition) throws ValidationException {
if(condition){
MapBindingResult errors= new MapBindingResult(new HashMap<>(), target.getClass().getSimpleName());
// validate all constraints associated to MyGroup (even in my nested objects)
validator.validate(parent, errors, Parent.MyGroup.class);
if(errors.hasErrors()) throw new ValidationException(errors); // A custom exception
}
}
If a validation error is detected in my child field 'aField', the first associated validation error code (see FieldError.codes) will be 'NotBlank.Parent.afield'.
I should have better checked @Valid
documentation.