title: How to assign Set elements to form field in Thymeleaf
body: <p>I can see List being used successfully in Thymeleaf forms in 
  <a href="http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#dynamic-fields" rel="nofollow noreferrer">http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#dynamic-fields</a></p>
  
  <pre><code>&lt;tr th:each="row,rowStat : *{rows}"&gt;
    &lt;td th:text="${rowStat.count}"&gt;1&lt;/td&gt;
    &lt;td&gt;
      &lt;select th:field="*{rows[__${rowStat.index}__].variety}"&gt;&lt;!-- how to do this with Set? --&gt;
        &lt;option th:each="var : ${allVarieties}" 
                th:value="${var.id}" 
                th:text="${var.name}"&gt;Thymus Thymi&lt;/option&gt;
      &lt;/select&gt;
    &lt;/td&gt;
    ..
  &lt;/tr&gt;
  </code></pre>
  
  <p>Can I do the same with Set instead of List? Specifically the line with comment in code.
  How do I assign Set elements to th:field?</p>
  
  <p><strong>Update 1</strong></p>
  
  <p>I used this in my project and proceeded to use Set and on submit/add new row, it gives below error. It does not even reach corresponding controller method.</p>
  
  <blockquote>
    <p>org.springframework.beans.InvalidPropertyException: Invalid property 'catDescrDts[0]' of bean class [ae.tbits.atn.aiwacore.common.model.CatDescr]: Illegal attempt to get property 'catDescrDts' threw exception; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'catDescrDts[0]' of bean class [ae.tbits.atn.aiwacore.common.model.CatDescr]: Cannot get element with index 0 from Set of size 0, accessed using property path 'catDescrDts[0]'</p>
  </blockquote>
  
  <p>CatDescrDts correspond to the rows in the example, it has many to one relation with CatDescr entity.</p>
  
  <p>Stack trace</p>
  
  <pre><code>Caused by: org.springframework.beans.InvalidPropertyException: Invalid property 'catDescrDts[0]' of bean class [ae.tbits.atn.aiwacore.common.model.CatDescr]: Cannot get element with index 0 from Set of size 0, accessed using property path 'catDescrDts[0]'
  at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:661)
  ... 51 more
  2017-07-13 16:23:57 ERROR ErrorController:19 - Exception during execution of SpringSecurity application
  org.springframework.beans.InvalidPropertyException: Invalid property 'catDescrDts[0]' of bean class [ae.tbits.atn.aiwacore.common.model.CatDescr]: Illegal attempt to get property 'catDescrDts' threw exception; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'catDescrDts[0]' of bean class [ae.tbits.atn.aiwacore.common.model.CatDescr]: Cannot get element with index 0 from Set of size 0, accessed using property path 'catDescrDts[0]'
  at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:708)
  at org.springframework.beans.AbstractNestablePropertyAccessor.getNestedPropertyAccessor(AbstractNestablePropertyAccessor.java:836)
  at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyAccessorForPropertyPath(AbstractNestablePropertyAccessor.java:813)
  at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:270)
  at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:95)
  at org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:834)
  at org.springframework.validation.DataBinder.doBind(DataBinder.java:730)
  at org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:192)
  at org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:106)
  at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.bindRequestParameters(ServletModelAttributeMethodProcessor.java:150)
  at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:114)
  at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
  at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
  at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
  at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
  at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
  at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
  at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
  at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
  at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
  at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
  at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
  at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
  at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
  at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
  at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
  at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
  at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
  at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
  at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
  at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
  at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
  at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
  at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
  at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
  at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
  at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
  at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
  at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
  at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
  at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
  at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284)
  at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)
  at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
  at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174)
  at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
  at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  at java.lang.Thread.run(Thread.java:745)
  
  Caused by: org.springframework.beans.InvalidPropertyException: Invalid property 'catDescrDts[0]' of bean class [ae.tbits.atn.aiwacore.common.model.CatDescr]: Cannot get element with index 0 from Set of size 0, accessed using property path 'catDescrDts[0]'
  at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:661)
  ... 51 more
  </code></pre>
  
  <p><strong>Update 2</strong></p>
  
  <p>Putting some code..</p>
  
  <ol>
  <li>When create is first called, form shows up fine with empty row. </li>
  <li>When I click on save or add new row, that error throws up before controller save() is called. </li>
  <li>If I comment out th:field line, error is gone.</li>
  </ol>
  
  <p>Controller</p>
  
  <pre><code>@GetMapping({"/create"})
  public String create(ModelMap model){
      CatDescr catDescr = new CatDescr();         
      //add 1 empty row for catDescrDt
      int noOfCatDescrDts = 1;
      catDescr.setCatDescrDts(getNewCatDescrDts(noOfCatDescrDts, catDescr));  
      model.addAttribute("catDescr", catDescr);   
      return "catDescr/create";
  }
  
  @PostMapping(value="/create", params={"save"})
  public String save(final CatDescr catDescr
          , final BindingResult bindingResult, final ModelMap model){     
      ...
      CatDescr updatedCatDescr = catDescrService.save(catDescr);  
      model.clear();
      return "redirect:/catDescr/create";
  
  }
  
  @RequestMapping(value="/create", params={"addCatDescrDtRow"})
  public String addCatDescrDtRow(ModelMap model, final CatDescr catDescr, final BindingResult bindingResult) {
      catDescr.getCatDescrDts().add(new CatDescrDt());
      ...
      return "catDescr/create";
  }
  </code></pre>
  
  <p>View</p>
  
  <pre><code>&lt;ul th:each="item, stat: *{catDescrDts}"&gt;
  &lt;li&gt;
      &lt;input type="text" th:field="*{catDescrDts[__${stat.index}__].name}" th:id="${'catDescrDts'+stat.index+'.name'}"&gt;
  &lt;/li&gt;
  </code></pre>
  
  <p></p>