title: Null fields in Thymeleaf form using Spring Boot, other fields fine
body: <p>I'm relatively new to Spring Boot. Currently, I'm making a Spring Boot application with user registration system but I've run into an issue. Some of the fields in a form are registering as ‘null’ on the back end, despite the request being posted correctly.</p>
  <p>I have a HTML/ Thymeleaf form which submits 8 fields to create a 'User' object. This is the form:</p>
  <pre><code>&lt;form th:action=&quot;@{/users/register_attempt}&quot; th:object=&quot;${user}&quot;
        method=&quot;post&quot; style=&quot;max-width: 600px; margin: 0 auto;&quot;&gt;
      &lt;div class=&quot;m-3&quot;&gt;
          &lt;div class=&quot;form-group row&quot;&gt;
              &lt;label class=&quot;col-4 col-form-label&quot;&gt;DOB: &lt;/label&gt;
              &lt;div class=&quot;col-8&quot;&gt;
                  &lt;input type=&quot;text&quot; th:field=&quot;*{dob}&quot; class=&quot;form-control&quot; th:required=&quot;required&quot; /&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;div class=&quot;form-group row&quot;&gt;
              &lt;label class=&quot;col-4 col-form-label&quot;&gt;First Name: &lt;/label&gt;
              &lt;div class=&quot;col-8&quot;&gt;
                  &lt;input type=&quot;text&quot; th:field=&quot;*{name}&quot; class=&quot;form-control&quot; th:required=&quot;required&quot; /&gt;
              &lt;/div&gt;
          &lt;/div&gt;
  
          &lt;div class=&quot;form-group row&quot;&gt;
              &lt;label class=&quot;col-4 col-form-label&quot;&gt;Surname: &lt;/label&gt;
              &lt;div class=&quot;col-8&quot;&gt;
                  &lt;input type=&quot;text&quot; th:field=&quot;*{surname}&quot; class=&quot;form-control&quot; th:required=&quot;required&quot; /&gt;
              &lt;/div&gt;
          &lt;/div&gt;
  
          &lt;div class=&quot;form-group row&quot;&gt;
              &lt;label class=&quot;col-4 col-form-label&quot;&gt;PPSN: &lt;/label&gt;
              &lt;div class=&quot;col-8&quot;&gt;
                  &lt;input type=&quot;text&quot; th:field=&quot;*{ppsn}&quot; class=&quot;form-control&quot; th:required=&quot;required&quot; /&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;div class=&quot;form-group row&quot;&gt;
              &lt;label class=&quot;col-4 col-form-label&quot;&gt;Address: &lt;/label&gt;
              &lt;div class=&quot;col-8&quot;&gt;
                  &lt;input type=&quot;text&quot; th:field=&quot;*{address}&quot; class=&quot;form-control&quot; th:required=&quot;required&quot; /&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;div class=&quot;form-group row&quot;&gt;
              &lt;label class=&quot;col-4 col-form-label&quot;&gt;Phone Number: &lt;/label&gt;
              &lt;div class=&quot;col-8&quot;&gt;
                  &lt;input type=&quot;number&quot; th:field=&quot;*{phone}&quot; class=&quot;form-control&quot;  /&gt;
              &lt;/div&gt;
          &lt;/div&gt;
  
          &lt;div class=&quot;form-group row&quot;&gt;
              &lt;label class=&quot;col-4 col-form-label&quot;&gt;E-mail: &lt;/label&gt;
              &lt;div class=&quot;col-8&quot;&gt;
                  &lt;input type=&quot;email&quot; th:field=&quot;*{email}&quot; class=&quot;form-control&quot; th:required=&quot;required&quot; /&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;div class=&quot;form-group row&quot;&gt;
              &lt;label class=&quot;col-4 col-form-label&quot;&gt;Password: &lt;/label&gt;
              &lt;div class=&quot;col-8&quot;&gt;
                  &lt;input type=&quot;password&quot; th:field=&quot;*{password}&quot; class=&quot;form-control&quot;
                         required minlength=&quot;6&quot; maxlength=&quot;10&quot; th:required=&quot;required&quot;/&gt;
              &lt;/div&gt;
          &lt;/div&gt;
  
          &lt;div&gt;
              &lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;Sign Up&lt;/button&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/form&gt;
  </code></pre>
  <p>And here is the model that the form code is meant to mimic:</p>
  <pre><code>public class User {
  @Id
  @GeneratedValue
  private Long id;
  
  @NotBlank
  private String dob;
  @NotBlank
  private String name;
  @NotBlank
  private String surname;
  @NotBlank
  private String ppsn;
  @NotBlank
  private String address;
  @NotBlank
  private String phone;
  @NotBlank
  @Column(unique = true)
  private String email;
  
  private String nextApptId;
  
  private String dose1Date;
  
  private String dose2Date;
  
  private String lastLogin;
  @NotBlank
  private String password;
  
  public User() {
      super();
  }
  
  public User(String dob, String name, String surname, String ppsn, String address, String phone, String email, String password) {
      super();
      this.dob = dob;
      this.name = name;
      this.surname = surname;
      this.ppsn = ppsn;
      this.address = address;
      this.phone = phone;
      this.email = email;
      this.password = password;
  }
   public Long getId() {
      return id;
  }
  
  public String getDob() {
      return dob;
  }
  
  public String getName() {
      return name;
  }
  
  public String getSurname() {
      return surname;
  }
  
  public String getPpsn() {
      return ppsn;
  }
  
  public String getAddress() {
      return address;
  }
  
  public void setAddress(String address) {
      this.address = address;
  }
  
  public String getPhone() {
      return phone;
  }
  
  public void setPhone(String phone) {
      this.phone = phone;
  }
  
  public String getEmail() {
      return email;
  }
  
  public void setEmail(String email) {
      this.email = email;
  }
  
  public String getNextApptId() {
      return nextApptId;
  }
  
  public void setNextApptId(String apptId) {
      this.nextApptId = apptId;
  }
  
  public String getDose1Date() {
      return dose1Date;
  }
  
  public void setDose1Date(String dose1Date) {
      this.dose1Date = dose1Date;
  }
  
  public String getDose2Date() {
      return dose2Date;
  }
  
  public void setDose2Date(String dose2Date) {
      this.dose2Date = dose2Date;
  }
  
  public String getLastLogin() {
      return lastLogin;
  }
  
  public void setLastLogin(String lastLogin) {
      this.lastLogin = lastLogin;
  }
  
  public String getPassword() {
      return password;
  }
  
  public void setPassword(String password) {
      this.password = password;
  }
  }
  </code></pre>
  <p>But for some reason I can't figure out, the first four fields - i.e. Dob (date of birth), Name, Surname, and PPSN, are producing a null error when instantiating the user object on the server side, e.g.:</p>
  <pre><code>     `Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 4 errors&lt;EOL&gt;
  Field error in object 'user' on field 'dob': rejected value [null]; codes [NotBlank.user.dob,NotBlank.dob,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.dob,dob]; arguments []; default message [dob]]; default message [must not be blank] `.
  </code></pre>
  <p>The other four fields, Address, Phone, Email, and Password appear to be working just fine.</p>
  <p>As far as I can make out, there it isn't a typo issue (forgive me if that ends up being the case). I have intercepted the Post request using Burp to check that the contents of the fields were making it out of the form and into the request, with the right names for the fields in my User class, and indeed they are all there as intended.</p>
  <p>I imagine this means that the issue is coming from how the back end controller code is interpreting this post request based on the model, but I have no real idea of how or where to start. Here is the current controller:</p>
  <pre><code>@GetMapping(&quot;/register&quot;)
      public String startRegistration(Model model) {
          model.addAttribute(&quot;user&quot;, new User());
          return &quot;register&quot;;
      }  
  
  @PostMapping(&quot;/register_attempt&quot;)
      public String registerAttempt(@Valid User newUser) {
          BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
          String encodedPassword = passwordEncoder.encode(newUser.getPassword());
          newUser.setPassword(encodedPassword);
          userRepository.save(newUser);
          return &quot;registered_successfully&quot;;
      }
  </code></pre>
  <p>EDIT: Further debugging &amp; clarification with issue persisting</p>
  <p>Removing the <code>@Valid</code> annotation from the Post Mapping and using old fashioned print statements shows the same results - that the first four fields are null, for no obvious reason.</p>
  <pre><code>    @PostMapping(&quot;/register_attempt&quot;)
  public String registerAttempt(@ModelAttribute(&quot;user&quot;) User newUser) {
      System.out.println(&quot;Saving user &quot;);
      System.out.println(&quot;Name &quot; + newUser.getName());
      System.out.println(&quot;Last Name &quot; + newUser.getSurname());
      System.out.println(&quot;PPSN &quot; +newUser.getPpsn());
      System.out.println(&quot;DOB &quot; +newUser.getDob());
      System.out.println(&quot;email &quot; +newUser.getEmail());
      System.out.println(&quot;address &quot; +newUser.getAddress());
      System.out.println(&quot;encrypted password &quot; +newUser.getPassword());
      System.out.println(&quot;Phone num &quot; +newUser.getPhone());
      userRepository.save(newUser);
      System.out.println(&quot;User saved&quot;);
      return &quot;registered_successfully&quot;;
  }
  </code></pre>
  <p>Using the following dummy data:</p>
  <p><a href="https://i.stack.imgur.com/Ant6G.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Ant6G.png" alt="The form Pre-submission" /></a></p>
  <p>Which sends this Post Request to the back end:</p>
  <p><a href="https://i.stack.imgur.com/ZN5WF.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ZN5WF.jpg" alt="Post Request as captured in burp after submission - all information is there as intended" /></a></p>
  <p>Results in these print statements:</p>
  <pre><code>Saving user 
  name null
  last Name null
  ppsn null
  dob null
  email foo@bar.com
  address Here and there
  password password
  Phone num 987654321
  </code></pre>
  <p>And these error messages:</p>
  <pre><code>javax.validation.ConstraintViolationException: Validation failed for classes [app.model.User] during persist time for groups [javax.validation.groups.Default, ]
  List of constraint violations:[
      ConstraintViolationImpl{interpolatedMessage='must not be blank', propertyPath=surname, rootBeanClass=class app.model.User, messageTemplate='{javax.validation.constraints.NotBlank.message}'}
      ConstraintViolationImpl{interpolatedMessage='must not be blank', propertyPath=dob, rootBeanClass=class app.model.User, messageTemplate='{javax.validation.constraints.NotBlank.message}'}
      ConstraintViolationImpl{interpolatedMessage='must not be blank', propertyPath=name, rootBeanClass=class app.model.User, messageTemplate='{javax.validation.constraints.NotBlank.message}'}
      ConstraintViolationImpl{interpolatedMessage='must not be blank', propertyPath=ppsn, rootBeanClass=class app.model.User, messageTemplate='{javax.validation.constraints.NotBlank.message}'}
  ]
  </code></pre>
  <p>If you have any insight into why this might be happening, I would very much appreciate it.</p>