title: Spring MVC: Request Scope, trying to update a Command Object with binder.setDisallowedFields
body: <p>I have this Object</p>
  
  <pre><code>public class Deportista implements Serializable {
  
      private static final long serialVersionUID = 6229604242306465153L;
  
      private String id;
      ...
  
      @NotNull(message="{field.null}")
      public String getId() {
          return id;
      }
      ...
  
  }
  </code></pre>
  
  <p>I have the following Controller's methods</p>
  
  <pre><code>@InitBinder(value="deportistaRegistrar")
  public void registrarInitBinder(WebDataBinder binder) {
      logger.info("&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; registrarInitBinder &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;");
  }
  
  @RequestMapping(value="/registrar.htm", method=RequestMethod.GET)
  public String crearRegistrarFormulario(Model model){
      logger.info("crearRegistrarFormulario GET");
      Deportista deportista = new Deportista();
      model.addAttribute("deportistaRegistrar", deportista);
      return "deportista.formulario.registro";
  }
  
  @RequestMapping(value="/registrar.htm", method=RequestMethod.POST)
  public String registrarPerson(@Validated @ModelAttribute("deportistaRegistrar") Deportista deportista, 
                                BindingResult result){
  
      logger.info("registrarPerson POST");
      logger.info("{}", deportista.toString());
  
      if(result.hasErrors()){
          logger.error("There are errors!!!!");
  
          for(ObjectError objectError : result.getAllErrors()){
              logger.error("Error {}", objectError);
          }
  
          return "deportista.formulario.registro";
      }
  
      logger.info("All fine!!!!");
      this.fakeMultipleRepository.insertDeportista(deportista);
      return "redirect:/manolo.htm";
  }
  </code></pre>
  
  <p>Until here the Controller is able to create a form (GET) and submit (POST) a <strong>new</strong> <em>command</em> object, <code>Validation</code> code works well.</p>
  
  <p>The problem is with the update.</p>
  
  <p>I have the following:</p>
  
  <pre><code>@InitBinder(value="deportistaActualizar")
  public void actualizarInitBinder(WebDataBinder binder) {
      logger.info("&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; actualizarInitBinder &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;");
      binder.setDisallowedFields("id");
  }
  </code></pre>
  
  <p>Observe I have <code>binder.setDisallowedFields("id")</code></p>
  
  <pre><code>public String crearActualizarFormulario(@PathVariable("id") String id, Model model){
      logger.info("crearActualizarFormulario GET");
      Deportista deportista = this.fakeMultipleRepository.findDeportista(id);
      model.addAttribute("deportistaActualizar", deportista);
      return "deportista.formulario.actualizacion";
  }   
  
  @RequestMapping(value="/{id}/actualizar.htm", method=RequestMethod.POST)
  public String actualizarPerson(@Validated @ModelAttribute("deportistaActualizar") Deportista deportista, 
                             BindingResult result){
  
      logger.info("actualizarPerson POST");
      logger.info("{}", deportista.toString());
  
      if(result.hasErrors()){
          logger.error("There are errors!!!!");
  
          for(ObjectError objectError : result.getAllErrors()){
              logger.error("Error {}", objectError);
          }
  
          return "deportista.formulario.actualizacion";
      }
  
      logger.info("All fine!!!!");
      this.fakeMultipleRepository.updateDeportista(deportista);
      return "redirect:/manolo.htm";
  }
  </code></pre>
  
  <p>The problem is: </p>
  
  <ul>
  <li>when the form or command has any error, the controller re-render the view and the form appear showing the error messages how is expected, <strong>but without the ID value</strong></li>
  </ul>
  
  <p>or </p>
  
  <ul>
  <li>if I try to update the object, of course keeping the id value, and without any error to simply proceed to update, it fails</li>
  </ul>
  
  <p>The following appears in the Console:</p>
  
  <pre><code>- -------- createCollections ---------------
  - &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; actualizarInitBinder &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;
  - Skipping URI variable 'id' since the request contains a bind value with the same name.
  - actualizarPerson POST
  - Deportista [id=null, nombre=Manuel, ...]
  - There are errors!!!!
  - Error Field error in object 'deportistaActualizar' on field 'id': rejected value [null]; codes [NotNull.deportistaActualizar.id,NotNull.id,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [deportistaActualizar.id,id]; arguments []; default message [id]]; default message [The field must be not empty]
  </code></pre>
  
  <p>The <strong>id</strong> is null. How I can around this problem keeping the <strong>Request Scope</strong>? </p>
  
  <p>I have an alternate controller which is working with <code>@SessionAttributes</code> and all works perfect. But since is a huge risk if the user has many tabs open in the same web browser, one for create and other for updating, all is going to be very wrong. According with <a href="https://stackoverflow.com/a/10799908">Spring MVC + Session attributes and multiple tabs</a>, request scope should be used instead of session scope. It has sense. </p>
  
  <p>Sadly <em>seems</em> Spring is not going to fix this:
  <a href="https://jira.spring.io/browse/SPR-4160" rel="nofollow noreferrer">@SessionAttributes doesn't work with tabbed browsing</a></p>
  
  <p><strong>Addition</strong></p>
  
  <p>According with your suggestion, I have the following:</p>
  
  <pre><code>@ModelAttribute("deportistaActualizar")
  public Deportista populateActualizarFormulario(@RequestParam(defaultValue="") String id){
      logger.info("populateActualizarFormulario - id: {}", id);
      if(id.equals(""))
          return null;
      else
          return this.fakeMultipleRepository.findDeportista(id);
  }
  </code></pre>
  
  <p>Observe the method uses <code>@RequestParam</code>, my problem is how update that method to work when the URL to update has the following style
  <code>http://localhost:8080/spring-utility/deportista/1/actualizar.htm</code>. There is no <em>param</em> in the URL, therefore <code>@RequestParam</code> is useless now.</p>
  
  <p>I already have read the Spring Reference documentation:
  <a href="http://docs.spring.io/spring/docs/4.0.7.RELEASE/spring-framework-reference/htmlsingle/#mvc-ann-modelattrib-methods" rel="nofollow noreferrer">Using @ModelAttribute on a method</a></p>
  
  <p><strong>Second Addition</strong></p>
  
  <p>Yes, you was right, and I did that yesterday, but I forget to share the following:</p>
  
  <pre><code>@ModelAttribute("deportistaActualizar")
  public Deportista populateActualizarFormulario(@PathVariable(value="id") String id){
      logger.info("populateActualizarFormulario - id: {}", id);
      if(id.equals(""))
          return null;
      else
          return this.fakeMultipleRepository.findDeportista(id);
  }
  </code></pre>
  
  <p>Since a <code>@ModelAttribute</code> is called always before by any <code>handler</code> method, the following URL fails <code>http://localhost:8080/spring-utility/deportista/registrar.htm</code>, the following appears on the page</p>
  
  <pre><code>HTTP Status 400 -
  type Status report
  message
  description The request sent by the client was syntactically incorrect.
  </code></pre>
  
  <p>Of course because the URL does not contains the expected <code>id</code>. Therefore I can't create new records to later edit/see.</p>
  
  <p>I can confirm, that for the following work:</p>
  
  <ul>
  <li><code>http://localhost:8080/spring-utility/deportista/1/detalle.htm</code></li>
  <li><code>http://localhost:8080/spring-utility/deportista/1/actualizar.htm</code></li>
  </ul>
  
  <p>the id (1) is retrieved.</p>
  
  <p>How I could resolve this? </p>
  
  <p>Thank You</p>