Hello,
I’m using GroupSequence to group constraints into simple and complex validations.
My goal is, that the complex validations are only performed, when the validation of the simple constraints did succeed, so that the complex validations assume that the simple constraints are met.
When combining GroupSequence with Valid to perform validations recursively, the conditional execution of the complex validations doesn’t work as I would expect.
In some cases the complex validations are performed, even if a recursive validation would find a violation of a simple constraint. This leads to a NullPointerException in the complex validation.
Here is an example:
import java.util.Arrays;
import java.util.List;
import javax.validation.GroupSequence;
import javax.validation.Valid;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.junit.Assert;
import org.junit.Test;
public class ValidationTest {
public interface ComplexValidations {}
@GroupSequence({ Whole.class, ComplexValidations.class })
public static class Whole {
@NotNull @Size(min=2, max=10) @Valid
public List<Part> parts;
@AssertTrue(groups = ComplexValidations.class)
public boolean isvalidSum() {
return parts.stream().mapToInt(part -> part.fraction).sum() == 100;
}
}
private static class Part {
@NotNull
public Integer fraction;
}
@Test
public void test() {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Whole whole = new Whole();
Part part = new Part();
part.fraction = null;
//size is too small, and parts[0].fraction is null, so ComplexValidations aren't performed
whole.parts = Arrays.asList(part);
String violations = validator.validate(whole).toString();
Assert.assertTrue(violations.contains("must not be null', propertyPath=parts[0].fraction"));
Assert.assertTrue(violations.contains("size must be between 2 and 10', propertyPath=parts"));
//size is now valid, but parts[0].fraction is still null
//so ComplexValidations should't be performed
whole.parts = Arrays.asList(part, part);
//NPE in isvalidSum because fraction is null and ComplexValidations are still performed
violations = validator.validate(whole).toString();
Assert.assertTrue(violations
.contains("must not be null', propertyPath=parts[0].fraction"));
}
}
Is this a Bug in the Validator or is something wrong in the code?