title: Spring MVC strange behavior - model attribute gets overridden when it isn't supposed to
body: <p><strong>Background info:</strong> I am developing a client MVC using Spring Boot which communicates with a REST API in the back-end which retrieves user information from a database (MongoDB). My view technology is Thymeleaf. </p>
  
  <p>Once a user logs in he is redirected to his home page where his personal info is displayed. He also has an option to edit his profile, so when he clicks on the "edit my profile" link he is sent to a form where can fill out whatever info he wants to edit and then click "save" to save the changes. </p>
  
  <p>Here are my session attributes:</p>
  
  <pre><code>@SessionAttributes({"credentials", "user"})
  </code></pre>
  
  <p>"credentials" is a session object of the instantiation of a class I made called Credentials, which has two fields: String username, and String password.</p>
  
  <p>"user" is a session object of the instantiation of a class I made called User, which has many fields like firstname, lastname, etc in addition to String username and String password. </p>
  
  <p><strong>Problem:</strong> </p>
  
  <p>When he edits his personal info by filling out the form, and when he changes his username and password, the username and password of the "credentials" object gets overriden! This happens even when I did not specify that the objects fields should be overridden. Superficially, this looks like spring MVC is confusing the username and password field of both Credentials and User, and somehow is overriding it. </p>
  
  <p>Here is where the session attributes for both user and credentials are set:</p>
  
  <pre><code>@RequestMapping(value = "/getBasicUser", method = RequestMethod.GET)
      public &lt;T&gt; String getBasicUser(@ModelAttribute("credentials") Credentials credentials,
              Model model, RedirectAttributes redirect) {
  
          RestTemplate restTemplate = new RestTemplate();
          String url = "http://localhost:9090/users/getBasicUser?username="
                  + credentials.getUsername();
          ResponseEntity&lt;User&gt; responseEntity = restTemplate.exchange(
                  url,
                  HttpMethod.GET,
                  new HttpEntity&lt;T&gt;(createHeaders(credentials.getUsername(),
                          credentials.getPassword())), User.class);
          User user;
          user = responseEntity.getBody();
  
          if (user != null) {
              **redirect.addFlashAttribute("user", user);** //now session attribute "user" is set. 
              return "redirect:/basicHome";
          } else {
              return "register_fail";
          }
      }
  
  @RequestMapping(value = "/login", method = RequestMethod.POST)
      public String login(**@ModelAttribute("credentials") Credentials credentials**, // session attribute "credentials" is set here
              RedirectAttributes redirect) {
  
          RestTemplate restTemplate = new RestTemplate();
          RoleInfo roleInfo = restTemplate.postForObject(
                  "http://localhost:9090/users/login", credentials,
                  RoleInfo.class);
  
          if (roleInfo != null) {
              if (roleInfo.isAdmin()) {
                  return "redirect:/adminHome";
              } else {
                  return "redirect:/getBasicUser";
              }
          } else {
              return "login_fail";
          }
      }
  </code></pre>
  
  <p>Now "credentials" stores the username and password of the logged-in user throughout the session and thymeleaf recognizes it like in the home page here:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"&gt;
  &lt;head&gt;
  &lt;title&gt;Home&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;h1&gt;Welcome, &lt;span th:text="${credentials.username}"&gt;&lt;/span&gt; &lt;/h1&gt;
  
      &lt;h2&gt;My profile:&lt;/h2&gt;
      &lt;a th:href="@{/edit}"&gt;Edit my profile&lt;/a&gt;
      &lt;br&gt;&lt;/br&gt;
      &lt;br&gt;&lt;/br&gt;
          &lt;table&gt;
              &lt;tr&gt;&lt;td&gt;Firstname:&lt;/td&gt; &lt;td th:text="${user.firstname}"&gt;&lt;/td&gt;&lt;/tr&gt;
              &lt;tr&gt;&lt;td&gt;Lastname:&lt;/td&gt; &lt;td th:text="${user.lastname}"&gt;&lt;/td&gt;&lt;/tr&gt;
              &lt;tr&gt;&lt;td&gt;Username:&lt;/td&gt; &lt;td th:text="${user.username}"&gt;&lt;/td&gt;&lt;/tr&gt;
              &lt;tr&gt;&lt;td&gt;Address:&lt;/td&gt; &lt;td th:text="${user.address}"&gt;&lt;/td&gt;&lt;/tr&gt;
              &lt;tr&gt;&lt;td&gt;City:&lt;/td&gt; &lt;td th:text="${user.city}"&gt;&lt;/td&gt;&lt;/tr&gt;
              &lt;tr&gt;&lt;td&gt;State:&lt;/td&gt; &lt;td th:text="${user.state}"&gt;&lt;/td&gt;&lt;/tr&gt;
              &lt;tr&gt;&lt;td&gt;Zip code:&lt;/td&gt; &lt;td th:text="${user.zipCode}"&gt;&lt;/td&gt;&lt;/tr&gt;
              &lt;tr&gt;&lt;td&gt;Email:&lt;/td&gt; &lt;td th:text="${user.email}"&gt;&lt;/td&gt;&lt;/tr&gt;
              &lt;tr&gt;&lt;td&gt;Phone number:&lt;/td&gt; &lt;td th:text="${user.phoneNumber}"&gt;&lt;/td&gt;&lt;/tr&gt;
              &lt;tr&gt;&lt;td&gt;&lt;hr&gt;&lt;/hr&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;/table&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>However, in this method below, the fields are overridden!</p>
  
  <pre><code>    @RequestMapping(value = "/edit", method = RequestMethod.PUT)
          public &lt;T&gt; String editProfile(@ModelAttribute("newUser") User user,
                  @ModelAttribute("credentials") Credentials credentials, Model model,
                  RedirectAttributes redirect) {
  
              RestTemplate restTemplate = new RestTemplate();
              String url = "http://localhost:9090/users/update?username=" + credentials.getUsername();
  
  // username and password shows the new fields that are entered, as expected, but credentials username and password ALSO shows the new username and password, and NOT the session attribute's log in username and password.
  
          System.out.println("username: " + user.getUsername());
          System.out.println("password: " + user.getPassword());
          System.out.println("credentials username: " + credentials.getUsername());
          System.out.println("credentials password: " + credentials.getPassword());
          HttpHeaders headers = createHeaders(credentials.getUsername(),
                  credentials.getPassword());
  
          @SuppressWarnings({ "unchecked", "rawtypes" })
          HttpEntity&lt;T&gt; entity = new HttpEntity(user, headers);
  
          ResponseEntity&lt;User&gt; responseEntity = restTemplate.exchange(url,
                  HttpMethod.PUT, entity, User.class);
  
          User returnedUser = responseEntity.getBody();
  
          if (returnedUser != null) {
              //credentials.setUsername(returnedUser.getUsername());
              //credentials.setPassword(returnedUser.getPassword());
              redirect.addFlashAttribute("user", returnedUser);
              redirect.addFlashAttribute("credentials", credentials);
              return "redirect:/basicHome";
          } else {
              return "redirect:/editFail";
          }
      }
  </code></pre>
  
  <p>I'm not even sure how spring can confuse one form backing bean or one object to another. </p>
  
  <p>Here is thymeleaf view of the edit page:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"&gt;
  &lt;head&gt;
  &lt;title&gt;Edit&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;form action="#" th:action="@{/edit}" th:object="${newUser}" th:method="put"&gt;
      &lt;table&gt;
          &lt;tr&gt;&lt;td&gt;First Name:&lt;/td&gt; &lt;td&gt;&lt;input type="text" th:value="${user.firstname}" id="firstname" name="firstname"/&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;Last Name:&lt;/td&gt; &lt;td&gt;&lt;input type="text" th:value="${user.lastname}" id="lastname" name="lastname"/&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;User Name:&lt;/td&gt; &lt;td&gt;&lt;input type="text" th:value="${user.username}" id="username" name="username"/&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;Password:&lt;/td&gt; &lt;td&gt;&lt;input type="password" th:value="${user.password}" id="password" name="password"/&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;Address:&lt;/td&gt; &lt;td&gt;&lt;input type="text" th:value="${user.address}" id="address" name="address"/&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;City:&lt;/td&gt; &lt;td&gt;&lt;input type="text" th:value="${user.city}" id="city" name="city"/&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;State:&lt;/td&gt; &lt;td&gt;&lt;input type="text" th:value="${user.state}" id="state" name="state"/&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;Zip Code:&lt;/td&gt; &lt;td&gt;&lt;input type="text" th:value="${user.zipCode}" id="zipCode" name="zipCode"/&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;Email:&lt;/td&gt; &lt;td&gt;&lt;input type="text" th:value="${user.email}" id="email" name="email"/&gt;&lt;/td&gt;&lt;/tr&gt; 
          &lt;tr&gt;&lt;td&gt;Phone Number:&lt;/td&gt; &lt;td&gt;&lt;input type="text" th:value="${user.phoneNumber}" id="phoneNumber" name="phoneNumber"/&gt;&lt;/td&gt;&lt;/tr&gt;
      &lt;/table&gt;    
          &lt;hr&gt;&lt;/hr&gt;
          &lt;input type="submit" value="Save" name="editButton" /&gt;
      &lt;/form&gt;
  &lt;/body&gt;
  </code></pre>