Search code examples
validationjsf-2.2hibernate-validator

JSF 2.2 Controller Validation - Doesn't seem to fire


Hi I have this contrived controller:

@Model
@FieldMatch(first = "username", second = "usernameAgain", message = "The email fields must match")
public class HelloController implements Serializable {

    private static final long serialVersionUID = -8187960089787583270L;
    private String username;
    private String usernameAgain;

    private static final Logger LOG = LoggerFactory.getLogger(HelloController.class.getName());

    // final static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    // private static Validator validator = factory.getValidator();

    public String login() {

        // final Set<ConstraintViolation<HelloController>> violations = validator.validate(this);
        // LOG.info(violations.toString());
        final boolean valid = isValid();
        LOG.info("{VALID: " + valid + "},{USERNAME: " + username + "}, {USERNAMEAGAIN: " + usernameAgain + "}");

        return null;

    }

    @AssertTrue(message = "NO VALID")
    private boolean isValid() {
       return username.equals(usernameAgain);
    }

In looking for a proper way to validate fields are equal, I started researching jsf validation, which led me to hibernate's implementation. I also came across this gem: Cross field validation with Hibernate Validator (JSR 303)

So if I put @NotNull/@Size/etc... on username and usernameAgain that validation works.

However when I "login()" neither the FieldMatch or the isValid() (see above stack question as to why I thought that would work, though I couldn't find it in the documentation) seem to fire. (logging, debugging) If i force isValid() that doesn't throw an error either.

If i manually run

validator.validate(this);

then i seem to get the desired affect.

The unit tests I wrote initially all seem to work, but again in those I'm manually running Hibernates Validator on it as I thought it implemented the same bean validation JSF does during its validation?

It seems either there is a disconnect in my mind about what kind of validations are going on between standard BeanValidation and JSF Validation, or i have something wrong in my setup. Of course there is the third option, i'm totally clueless.

Thanks in advance.


Solution

  • That's because JSF does not integrate with Bean Validation via Validator#validate, but rather Validator#validateProperty. The latter only allows the validation of single properties and does not support cross field validation. It is basically a shortcoming of the JSF to Bean Validation integration. There are discussions to support class level constraints in future versions of this integration, but for now they just won't work. Check the JSF spec for integration details.