Nested cross field validation


#1

Hi!

Maybe I’m doing something incorrectly, but I’d like to kindly ask you if there is a better way of doing deeply nested cross-validation, as I find Bean Validation API hard to use i such cases.
Hope that it’s a good place to search for an answer.

I’ve created https://github.com/perceptron8/bval-example/ so you can see what it’s all about.

It’s clear that there is no way to implement Z Validation without access to X fields, therefore one must create class-level constraint for X. Someone could argue that it’s just a matter of adding back-refs from Z to Y and from Y to X and annotating Z, but a) that’s impossible if you don’t own the model, b) Z’s parent may be context dependent (imagine that at least X->A->Z and X->B->Z are possible). I’m stuck with both a) and b).

Please compare /src/main/java/bval/MyValidator.java with /src/main/java/bval/MyConstraintValidator.java.

AFAIK it’s impossible to create nested context and reuse it, mainly because there’s no way to specify path components without giving error message first.

What I mean is that I can’t write something like

ConstraintValidatorContext nestedContext = context
      .startNestedContextWithoutMessage()
      .addPropertyNode(...)
      ...
      .stopNestedContextAndPointHere()
      .inIterable().atIndex(...); // this could point to x.y[yi].z[zi]

and then maybe

nestedContext
   .buildConstraintViolationWithTemplate(...)
   .addPropertyNode(...)
   .addConstraintViolation()
   .disableDefaultConstraintViolation(); // this could resolve to x.y[yi].z[zi].val

or just

nestedContext
   .addConstraintViolation(); // same as above, but with default message

Instead, I’m forced to recreate whole path every time. No code reuse seems to be possible. Because of that, I must confess that most of the time, I find Spring’s Errors stack-like behavior much more pleasant to use - despite not being type-safe.

Is there something I missed?

Best regards
Michał