title: Spring @Valid not working as it should in Post controller (multi-part)
body: <p>I have a form which is supposed to upload an image with a @ModelAttribute alongside it. The issue happens when I try to validate some constraints in that object. What happens is that the controller method code does not execute, I just get thrown exception constraints</p>
  
  <pre><code>Field error in object 'employee' on field 'details.name': rejected value []; codes [Size.employee.details.name,Size.details.name,Size.name,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employee.details.name,details.name]; arguments []; default message [details.name],20,1]; default message [*Must be between 1 and 20 letters]
  Field error in object 'employee' on field 'details.lastName': rejected value []; codes [NotBlank.employee.details.lastName,NotBlank.details.lastName,NotBlank.lastName,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employee.details.lastName,details.lastName]; arguments []; default message [details.lastName]]; default message [*Please provide a valid last name]
  Field error in object 'employee' on field 'details.name': rejected value []; codes [NotBlank.employee.details.name,NotBlank.details.name,NotBlank.name,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employee.details.name,details.name]; arguments []; default message [details.name]]; default message [*Please provide a valid first name]
  Field error in object 'employee' on field 'jobOccupation': rejected value []; codes [NotBlank.employee.jobOccupation,NotBlank.jobOccupation,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employee.jobOccupation,jobOccupation]; arguments []; default message [jobOccupation]]; default message [*Employee must have an occupation]
  Field error in object 'employee' on field 'details.lastName': rejected value []; codes [Size.employee.details.lastName,Size.details.lastName,Size.lastName,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employee.details.lastName,details.lastName]; arguments []; default message [details.lastName],20,1]; default message [*Must be between 1 and 20 letters]
  </code></pre>
  
  <p>If all fields are populated (excluding the image because it doesn't have any constraints) Everything works fine, but I need that validation.</p>
  
  <p>This is my form</p>
  
  <pre><code>&lt;form class="mar-clearfix"  th:action="@{/admin/staff/create/employee}" id="emp-form"
                                      th:object="${employee}" enctype="multipart/form-data"
                                       method="post"&gt;
                                          &lt;div class="col s12 xl6"&gt;
                                              &lt;div class="field-wrapper"&gt;
                                              &lt;p th:if="${#fields.hasErrors('details.name')}" th:errors="*{details.name}" class="error"&gt;&lt;/p&gt;
                                                  &lt;div class="input-field"&gt;
                                                      &lt;input type="text" th:field="*{details.name}" id="emp-f-name"&gt;
                                                      &lt;label for="emp-f-name"&gt;First Name&lt;/label&gt;
                                                  &lt;/div&gt;
                                              &lt;/div&gt;
                                              &lt;div class="field-wrapper"&gt;
                                              &lt;p th:if="${#fields.hasErrors('details.lastName')}" th:errors="*{details.lastName}" class="error"&gt;&lt;/p&gt;
                                                  &lt;div class="input-field"&gt;
                                                      &lt;input type="text" th:field="*{details.lastName}" id="emp-l-name"&gt;
                                                      &lt;label for="emp-l-name"&gt;Last Name&lt;/label&gt;
                                                  &lt;/div&gt;
                                              &lt;/div&gt;
                                              &lt;div class="field-wrapper"&gt;
                                                  &lt;div class="input-field"&gt;
                                                      &lt;input type="email" th:field="*{email}" id="emp-email"&gt;
                                                      &lt;label for="emp-email"&gt;Email&lt;/label&gt;
                                                  &lt;/div&gt;
                                              &lt;/div&gt;
                                              &lt;div class="field-wrapper"&gt;
                                                  &lt;div class="input-field"&gt;
                                                      &lt;label for="emp-birthday"&gt;Birthday&lt;/label&gt;
                                                      &lt;input type="text" id="emp-birthday" th:field="*{details.dateOfBirth}" class="datepicker"&gt;
                                                  &lt;/div&gt;
                                              &lt;/div&gt;
                                          &lt;/div&gt;
                                          &lt;div class="col s12 xl6"&gt;
                                              &lt;div class="field-wrapper"&gt;
                                              &lt;p th:if="${#fields.hasErrors('jobOccupation')}" th:errors="*{jobOccupation}" class="error"&gt;&lt;/p&gt;
                                                  &lt;div class="input-field"&gt;
                                                      &lt;input type="text" th:field="*{jobOccupation}" id="emp-job"&gt;
                                                      &lt;label for="emp-job"&gt;Job Ocupation&lt;/label&gt;
                                                  &lt;/div&gt;
                                              &lt;/div&gt;
                                              &lt;div class="field-wrapper"&gt;
                                                  &lt;div class="input-field"&gt;
                                                      &lt;select th:field="*{details.gender}"&gt;
                                                          &lt;option th:value="${T(com.mypackage.Genders).MALE}"&gt;Male&lt;/option&gt;
                                                          &lt;option th:value="${T(com.mypackage.Genders).FEMALE}"&gt;Female&lt;/option&gt;
                                                      &lt;/select&gt;
                                                  &lt;/div&gt;
                                              &lt;/div&gt;
                                              &lt;div class="field-wrapper" style="margin-top:23px"&gt;
                                                  &lt;div class="input-field"&gt;
                                                      &lt;select th:field="*{roles}" multiple&gt;
                                                          &lt;option th:value="null" disabled selected&gt;Select roles&lt;/option&gt;
                                                        &lt;option th:each="item : ${roles}"  th:value="${{item}}" 
                                      th:text="${item.role}" &gt;&lt;/option&gt;
                                                      &lt;/select&gt;
                                                  &lt;/div&gt;
                                              &lt;/div&gt;
                                              &lt;div class="field-wrapper" style="margin-top:23px"&gt;
                                                  &lt;div class="file-field input-field"&gt;
                                                      &lt;div class="btn"&gt;
                                                          &lt;span&gt;Profile img&lt;/span&gt;
                                                          &lt;input type="file" name="image"&gt;
                                                      &lt;/div&gt;
                                                      &lt;div class="file-path-wrapper"&gt;
                                                          &lt;input class="file-path validate" type="text"&gt;
                                                      &lt;/div&gt;
                                                  &lt;/div&gt;
                                              &lt;/div&gt;
                                          &lt;/div&gt;
                                      &lt;/form&gt;
  </code></pre>
  
  <p>Controller method</p>
  
  <pre><code>@PostMapping(value = "/admin/staff/create/employee")
          public ModelAndView createEmployee(@ModelAttribute ("employee") @Valid Employee employee
                  ,@RequestPart("image")MultipartFile image, BindingResult result) {
              ModelAndView mav = new ModelAndView();
              mav.setViewName("admin/admin_layout");
              mav.addObject("page", "employee_create");
              mav.addObject("roles",service.getEmployeeRoles());
              System.out.println("saving");
              if(result.hasErrors()) {
                  System.out.println("has errors");
                  return mav;}}
  </code></pre>
  
  <p>I've tried adding @RequestPart before @ModelAttribute but that does not seem to help. Also when i remove @RequestPart image and enctype from form everything works fine, errors get written correctly into corresponding th:error fields. My question is why is this happening when trying to upload an image with the form and is there any way around it? Thanks.</p>