title: Cross field bean validation - why you no work
body: <p>I've got a little problem here with my application. I'd like to check if fields password and confirm password match together, so I tried to do it like in the first answer for this question: <a href="https://stackoverflow.com/questions/1972933/cross-field-validation-with-hibernate-validator-jsr-303">Cross field validation with Hibernate Validator (JSR 303)</a></p>
  
  <p>The problem is that it actually doesn't work and I HAVE NO IDEA WHY. Please, help me! This is my first post here, so please don't be too harsh for me.</p>
  
  <p>Here's my Annotation :</p>
  
  <pre><code>/*
   * To change this template, choose Tools | Templates
   * and open the template in the editor.
   */
  package pl.lodz.p.zsk.ssbd2012.ssbd12.ValidationConstraints;
  
  import java.lang.annotation.*;
  import javax.validation.Constraint;
  import javax.validation.Payload;
  
  /**
   *
   * @author lukasz
   */
  @Documented
  @Constraint(validatedBy = FieldMatchValidator.class)
  @Target({ElementType.TYPE})
  @Retention(RetentionPolicy.RUNTIME)
  public @interface FieldMatch {
  
  String message() default "{pl.lodz.p.zsk.ssbd2012.ssbd12.ValidationConstraints.FieldMatch}";
  
  Class&lt;?&gt;[] groups() default {};
  
  Class&lt;? extends Payload&gt;[] payload() default {};
  
  String first();
  
  String second();
  }
  </code></pre>
  
  <p>Here's my ValidatorClass:</p>
  
  <pre><code>/*
   * To change this template, choose Tools | Templates
   * and open the template in the editor.
   */
  package pl.lodz.p.zsk.ssbd2012.ssbd12.ValidationConstraints;
  
  import java.lang.reflect.InvocationTargetException;
  import java.util.logging.Level;
  import java.util.logging.Logger;
  import javax.validation.ConstraintValidator;
  import javax.validation.ConstraintValidatorContext;
  import org.apache.commons.beanutils.BeanUtils;
  
  /**
   *
   * @author lukasz
   */
  public class FieldMatchValidator implements ConstraintValidator&lt;FieldMatch, Object&gt; {
  
      private String firstFieldName;
      private String secondFieldName;
  
      @Override
      public void initialize(FieldMatch constraintAnnotation) {
          firstFieldName = constraintAnnotation.first();
          secondFieldName = constraintAnnotation.second();
      }
  
      @Override
      public boolean isValid(Object value, ConstraintValidatorContext context) {
          try {
              String sFirstField = BeanUtils.getProperty(value, firstFieldName);
              String sSecondField = BeanUtils.getProperty(value, secondFieldName);
              if(sFirstField.equals(sSecondField)){
                  return true;
              }
          } catch (IllegalAccessException ex) {
              Logger.getLogger(FieldMatchValidator.class.getName()).log(Level.SEVERE, null, ex);
          } catch (InvocationTargetException ex) {
          Logger.getLogger(FieldMatchValidator.class.getName()).log(Level.SEVERE, null, ex);
          } catch (NoSuchMethodException ex) {
          Logger.getLogger(FieldMatchValidator.class.getName()).log(Level.SEVERE, null, ex);
          }
          return false;
      }
  }
  </code></pre>
  
  <p>And here's my bean:</p>
  
  <pre><code>/*
   * To change this template, choose Tools | Templates
   * and open the template in the editor.
   */
  package pl.lodz.p.zsk.ssbd2012.ssbd12.Beans;
  
  import javax.ejb.EJB;
  import javax.faces.bean.ManagedBean;
  import javax.faces.bean.RequestScoped;
  import javax.validation.constraints.Pattern;
  import javax.validation.constraints.Size;
  import pl.lodz.p.zsk.ssbd2012.ssbd12.ValidationConstraints.CheckEmail;
  import pl.lodz.p.zsk.ssbd2012.ssbd12.ValidationConstraints.FieldMatch;
  import pl.lodz.p.zsk.ssbd2012.ssbd12.entities.Account;
  import pl.lodz.p.zsk.ssbd2012.ssbd12.mok.endpoint.MokEndpointLocal;
  
  /**
   *
   * @author krzys
   * @author lukasz
   */
  
  @ManagedBean
  @RequestScoped
  @FieldMatch(first = "password", second = "password2", message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.ValidationConstraints.FieldMatch}")
  public class RegisterBean {
  
      /**
       * Creates a new instance of RegisterBean
       */
  
      @EJB
      MokEndpointLocal endpoint;
  
      @Size(min = 3, max = 16, message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.Beans.RegisterBean.login.size}")
      @Pattern(regexp = "[a-zA-Z0-9]+", message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.Beans.RegisterBean.login.invalid}")
      private String login;
  
      @Size(min = 6, max = 64, message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.Beans.RegisterBean.password.size}")
      @Pattern(regexp = "[a-zA-Z0-9]+", message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.Beans.RegisterBean.password.invalid}")
      private String password;
  
      private String password2;
  
      @Pattern(regexp = "[A-Ż][a-ż]+", message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.Beans.RegisterBean.name.invalid}")
      private String name;
  
      @Pattern(regexp = "[A-Ż][a-ż]+", message = "{pl.lodz.p.zsk.ssbd2012.ssbd12.Beans.RegisterBean.surname.invalid}")
      private String surname;
  
      @CheckEmail
      private String email = "";
  
  
      /**
       * @return the login
       */
      public String getLogin() {
          return login;
      }
  
      /**
       * @param login the login to set
       */
      public void setLogin(String login) {
          this.login = login;
      }
  
      /**
       * @return the password
       */
      public String getPassword() {
          return password;
      }
  
      /**
       * @param password the password to set
       */
      public void setPassword(String password) {
          this.password = password;
      }
  
      public String getPassword2() {
          return password2;
      }
  
      public void setPassword2(String password2) {
          this.password2 = password2;
      }
  
      /**
       * @return the name
       */
      public String getName() {
          return name;
      }
  
      /**
       * @param name the name to set
       */
      public void setName(String name) {
          this.name = name;
      }
  
      public String getEmail() {
          return email;
      }
  
      public void setEmail(String email) {
          this.email = email;
      }
  
      public String register ()
      {
  //       Account account = new Account();
  //       account.setLogin(login);
  //       account.setHaslo(password);
  //       account.setImie(name);
  //       account.setNazwisko(surname);
  //       account.setEmail(email);
  //       endpoint.register(account);
         return "registerSucces";
      }
  
      /**
       * @return the surname
       */
      public String getSurname() {
          return surname;
      }
  
      /**
       * @param surname the surname to set
       */
      public void setSurname(String surname) {
          this.surname = surname;
      }
  }
  </code></pre>
  
  <p>And here's JSF:</p>
  
  <pre><code>&lt;?xml version='1.0' encoding='UTF-8' ?&gt;
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:f="http://java.sun.com/jsf/core"&gt;
  &lt;h:head&gt;
      &lt;h:outputStylesheet name="menu.css" library="css" /&gt;
      &lt;title&gt;#{messages.registration}&lt;/title&gt;
  &lt;/h:head&gt;
  
  &lt;h:body&gt;
      &lt;ui:composition template="./../resources/mainTemplate.xhtml"&gt;
  
          &lt;h4&gt;#{messages.registration}&lt;/h4&gt;
      &lt;ui:define name="content"&gt;
          &lt;h4&gt;#{messages.registration}&lt;/h4&gt;
          &lt;h1&gt;#{messages.registrationInfo1}&lt;/h1&gt;
      #{messages.registrationInfo2}
      &lt;h:form&gt;
          &lt;h2&gt;
              &lt;h:outputText value="#{messages.loginForm}"/&gt;
              &lt;h:inputText id="login" value="#{registerBean.login}" /&gt;  
          &lt;/h2&gt;
          &lt;h2&gt;
              &lt;h:outputText value="#{messages.passwordForm}" /&gt;
              &lt;h:inputSecret id="password" value="#{registerBean.password}" /&gt;
          &lt;/h2&gt;
          &lt;h2&gt;
              &lt;h:outputText value="#{messages.repeatPasswordForm}"/&gt; 
              &lt;h:inputSecret id="confirm" value="#{registerBean.password2}" /&gt;
          &lt;/h2&gt;
          &lt;h2&gt;
              &lt;h:outputText value="#{messages.nameForm}"/&gt;
              &lt;h:inputText id="name" value="#{registerBean.name}" /&gt;
          &lt;/h2&gt;
          &lt;h2&gt;
              &lt;h:outputText value="#{messages.surnameForm}"/&gt;
              &lt;h:inputText id="surname" value="#{registerBean.surname}" /&gt;
          &lt;/h2&gt;
          &lt;h2&gt;
              &lt;h:outputText value="#{messages.emailForm}"/&gt;
              &lt;h:inputText id="email" value="#{registerBean.email}" /&gt;
          &lt;/h2&gt;
          &lt;h2&gt;    
              &lt;h:commandButton value="#{messages.send}" action="#{registerBean.register()}" /&gt;
          &lt;/h2&gt;
      &lt;/h:form&gt;
      &lt;/ui:define&gt;
      &lt;/ui:composition&gt;
  &lt;/h:body&gt;
  &lt;/html&gt;
  </code></pre>