title: Thymeleaf form validation
body: <p>I'm trying to validate password via double check and display an error with thymeleaf if passwords don't match </p>
  
  <p>The input form looks like this </p>
  
  <pre class="lang-java prettyprint-override"><code>package com.foxminded.university.domain;
  
  import javax.validation.constraints.AssertTrue;
  import javax.validation.constraints.Email;
  import javax.validation.constraints.NotNull;
  import javax.validation.constraints.Pattern;
  import javax.validation.constraints.Size;
  
  public class UserForm {
  
      @NotNull(message = "Can't be empty")
      @Size(min = 2, max = 30, message = "Must be more than 2 and less than 30 symbols")
      private String firstName;
  
      @NotNull(message = "Can't be empty")
      @Size(min = 2, max = 30, message = "Must be more than 2 and less than 30 symbols")
      private String lastName;
  
      @Email(message = "Enter valid e-mail" )
      private String email;
  
      @Pattern(regexp = "((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{6,20})",
      message = "Enter valid password")
      private String password;
  
      private String passwordRepeat;
  
      private boolean passwordsEqual;
  
      public String getFirstName() {
          return firstName;
      }
  
      public String getLastName() {
          return lastName;
      }
  
      public String getEmail() {
          return email;
      }
  
      public String getPassword() {
          return password;
      }
  
      public String getPasswordRepeat() {
          return passwordRepeat;
      }
      public void setFirstName(String firstName) {
          this.firstName = firstName;
      }
  
      public void setLastName(String lastName) {
          this.lastName = lastName;
      }
  
      public void setEmail(String email) {
          this.email = email;
      }
  
      public void setPassword(String password) {
          this.password = password;
      }
  
      public void setPasswordRepeat(String passwordRepeat) {
          this.passwordRepeat = passwordRepeat;
      }
  
      public void setPasswordsEqual(boolean passwordsEqual) {
          this.passwordsEqual = passwordsEqual;
      }
      @AssertTrue(message = "Passwords should match")
      public boolean isPasswordsEqual() {
          return password.equals(passwordRepeat);
      }
  }
  </code></pre>
  
  <p>And thymeleaf form row: </p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;div class="form-group"&gt;
              &lt;label&gt;Password&lt;/label&gt;
              &lt;input type="text" th:unless="${#fields.hasErrors('password')}" class="form-control" placeholder="Password"
                     th:field="*{password}"&gt;
              &lt;input type="text" th:if="${#fields.hasErrors('password')}" class="form-control alert-danger"
                     placeholder="Password" th:field="*{password}"&gt;
              &lt;span th:if="${#fields.hasErrors('password')}" th:errors="*{password}"&gt;&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class="form-group"&gt;
              &lt;label&gt; Repeat password&lt;/label&gt;
              &lt;input type="text" th:unless="${#fields.hasErrors('passwordsEqual')}" class="form-control"
                     placeholder="Password" th:field="*{passwordRepeat}"&gt;
              &lt;input type="text" th:if="${#fields.hasErrors('passwordsEqual')}" class="form-control alert-danger"
                     placeholder="Password" th:field="*{passwordRepeat}"&gt;
              &lt;span class="error" th:if="${#fields.hasErrors('passwordsEqual')}" th:errors="*{passwordsEqual}"&gt;&lt;/span&gt;
          &lt;/div&gt;&lt;div class="form-group"&gt;
              &lt;label&gt; Repeat password&lt;/label&gt;
              &lt;input type="text" th:unless="${#fields.hasErrors('passwordsEqual')}" class="form-control"
                     placeholder="Password" th:field="*{passwordRepeat}"&gt;
              &lt;input type="text" th:if="${#fields.hasErrors('passwordsEqual')}" class="form-control alert-danger"
                     placeholder="Password" th:field="*{passwordRepeat}"&gt;
              &lt;span class="error" th:if="${#fields.hasErrors('passwordsEqual')}" th:errors="*{passwordsEqual}"&gt;&lt;/span&gt;
          &lt;/div&gt;
  </code></pre>
  
  <p>But with this setup it doesn't load with exception <code>Caused by: java.lang.NullPointerException at com.foxminded.university.domain.UserForm.isPasswordsEqual(UserForm.java:74)</code></p>
  
  <p>So I'm not sure what should I annotate in from and whuch field to use in thymeleaf template for it to work?</p>