title: Spring MVC - Constraint validation with annotations - Error messages not displayed
body: <p>I would like to be able to display <strong>my entity field constraints validation errors</strong> in the web interface.</p>
  
  <p>For example, I have the following constraints defined on my entity:</p>
  
  <pre><code>@RooJavaBean
  @RooToString
  @RooJpaActiveRecord
  public class Member {
  
      @NotNull
      @Email
      @Column(unique = true)
      private String email;
  
      private String pseudo;
  
      @NotNull
      @Size(min = 6)
      private String password;
  
      @NotNull
      @Size(min = 2)
      private String firstName;
  
      @NotNull
      @Size(min = 2)
      private String lastName;
  
      @Temporal(TemporalType.DATE)
      @DateTimeFormat(pattern = "dd/MM/yyyy")
      private Date dateOfBirth;
  
      @NotNull
      @Enumerated
      private Orientation orientation;
  
      @NotNull
      private String token;
  
      @NotNull
      @Temporal(TemporalType.TIMESTAMP)
      @DateTimeFormat(pattern = "dd/MM/yyyy")
      private Date registrationDate;
  
      private boolean activated;
  }
  </code></pre>
  
  <p>I have also defined a helper javabean that I use in the spring mvc controller; here it is:</p>
  
  <pre><code>@RooJavaBean
  public class RegistrationInfo {
  
      private Member member;
  
      private String passwordConfirmation;
  
  }
  </code></pre>
  
  <p>Here is the relevant code in my spring mvc controller:</p>
  
  <pre><code>@RequestMapping(value = "/registration", method = RequestMethod.POST, produces = "text/html")
  public String registerMember(@ModelAttribute("registrationInfo") @Valid RegistrationInfo registrationInfo, Model model, BindingResult bindingResult) {
      if (!registrationInfo.getMember().getPassword().equals(registrationInfo.getPasswordConfirmation())) {
          bindingResult.addError(new ObjectError("member.password", "passwords don't match"));
      }
      if (!registrationService.isEmailAvailable(registrationInfo.getMember().getEmail())) {
          bindingResult.addError(new ObjectError("member.email", "email already used"));
      }
      if (bindingResult.hasErrors()) {
          //HOW TO ADD BEAN CONSTRAINTS VALIDATION ERRORS HERE????
          populateForm(model, registrationInfo);
          return "registration";
      }
      registrationService.registerMember(registrationInfo.getMember());
      return "redirect:/";
  }
  </code></pre>
  
  <p>from my UI:</p>
  
  <pre><code>&lt;div id="errors"&gt;
              &lt;ul th:if="${#fields.hasErrors('*')}"&gt;
                  &lt;li th:each="err : ${#fields.errors('*')}" th:text="${err}"&gt;&lt;/li&gt;
              &lt;/ul&gt;
          &lt;/div&gt;
  </code></pre>
  
  <p>However, as per now, the only errors that are going to be displayed are the errors I manually add (like this <code>bindingResult.addError</code>)...</p>
  
  <p>Can anyone please provide advice?</p>
  
  <p>EDIT: If I annotate the <code>member</code> variable with <code>@Valid</code>, I get this exception when validating the form:</p>
  
  <pre><code>org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 5 errors
  Field error in object 'registrationInfo' on field 'member.password': rejected value []; codes [Size.registrationInfo.member.password,Size.member.password,Size.password,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [registrationInfo.member.password,member.password]; arguments []; default message [member.password],2147483647,6]; default message [la taille doit �tre entre 6 et 2147483647]
  Field error in object 'registrationInfo' on field 'member.firstName': rejected value []; codes [Size.registrationInfo.member.firstName,Size.member.firstName,Size.firstName,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [registrationInfo.member.firstName,member.firstName]; arguments []; default message [member.firstName],2147483647,2]; default message [la taille doit �tre entre 2 et 2147483647]
  Field error in object 'registrationInfo' on field 'member.token': rejected value [null]; codes [NotNull.registrationInfo.member.token,NotNull.member.token,NotNull.token,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [registrationInfo.member.token,member.token]; arguments []; default message [member.token]]; default message [ne peut pas �tre nul]
  Field error in object 'registrationInfo' on field 'member.registrationDate': rejected value [null]; codes [NotNull.registrationInfo.member.registrationDate,NotNull.member.registrationDate,NotNull.registrationDate,NotNull.java.util.Date,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [registrationInfo.member.registrationDate,member.registrationDate]; arguments []; default message [member.registrationDate]]; default message [ne peut pas �tre nul]
  Field error in object 'registrationInfo' on field 'member.lastName': rejected value []; codes [Size.registrationInfo.member.lastName,Size.member.lastName,Size.lastName,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [registrationInfo.member.lastName,member.lastName]; arguments []; default message [member.lastName],2147483647,2]; default message [la taille doit �tre entre 2 et 2147483647]
      org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:111)
      org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:75)
      org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:156)
      org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
      org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
      org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
      org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
      org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
      org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
      org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
      org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
      org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
      org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:147)
      org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
      org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
      org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
      org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
      org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
  </code></pre>