title: POJO's collection not populated when submitting form
body: <p>I have a POJO named "FlashCard" which has a field named "links" which is collection (set) of Link objects.  <strong>When I submit a FORM to my Action all the POJO fields are populated with values from the form except the collection of "links".  I have no idea why this isn't getting populated.</strong></p>
  
  <p>Any advice on how to resolve this problem or how to better troubleshoot it would be much appreciated.</p>
  
  <p>Also, my POJO's collection is a Set.  Does it matter (or complicate things) that I'm using a Set and not a List?</p>
  
  <p>I'm including a simplified version of my code below.</p>
  
  <p>Here's my POJO:</p>
  
  <pre><code>public class FlashCard  implements java.io.Serializable {
  
   private int flashCardId;
   private String question;
   private String answer;
   private Set&lt;Link&gt; links = new HashSet&lt;Link&gt;(0);
  
  public FlashCard() {
  }
  
  public FlashCard(String question, String answer) {
      this.question = question;
      this.answer = answer;
  }
  public FlashCard(String question, String answer, Set&lt;Link&gt; links) {
     this.question = question;
     this.answer = answer;
     this.links = links;
  }
  
  public int getFlashCardId() {
      return this.flashCardId;
  }
  
  public void setFlashCardId(int flashCardId) {
      this.flashCardId = flashCardId;
  }
  public String getQuestion() {
      return this.question;
  }
  
  public void setQuestion(String question) {
      this.question = question;
  }
  public String getAnswer() {
      return this.answer;
  }
  
  public void setAnswer(String answer) {
      this.answer = answer;
  }
  public Set&lt;Link&gt; getLinks() {
      return this.links;
  }
  
  public void setLinks(Set&lt;Link&gt; links) {
      this.links = links;
  }
  }
  </code></pre>
  
  <p>Here's the POJO for the Link object:</p>
  
  <pre><code>public class Link  implements java.io.Serializable {
   private int linkId;
   private String url;
   private Set&lt;FlashCard&gt; flashcards = new HashSet&lt;FlashCard&gt;(0);
  
  public Link() {
  }
  public Link(String url) {
      this.url = url;
  }
  
  public Link(String url, Set&lt;FlashCard&gt; flashcards) {
     this.url = url;
     this.flashcards = flashcards;
  }
  
  public int getLinkId() {
      return this.linkId;
  }
  
  public void setLinkId(int linkId) {
      this.linkId = linkId;
  }
  public String getUrl() {
      return this.url;
  }
  
  public void setUrl(String url) {
      this.url = url;
  }
  public Set&lt;FlashCard&gt; getFlashcards() {
      return this.flashcards;
  }
  
  public void setFlashcards(Set&lt;FlashCard&gt; flashcards) {
      this.flashcards = flashcards;
  }
  }
  </code></pre>
  
  <p>Here's the relevant part of the Action</p>
  
  <pre><code>public class FlashCardAction extends FlashCardsAppBaseAction implements ModelDriven&lt;FlashCard&gt;, Preparable, SessionAware {
  
  static Logger logger = Logger.getLogger(FlashCardAction.class);
  
  FlashCard flashCard = new FlashCard();
  
  Map &lt;String,Object&gt; httpSession;
  
  Session session;
  FlashCardPersister fcPersister;
  
  public Map&lt;String, Object&gt; getHttpSession() {
      return httpSession;
  }
  
  public FlashCard getFlashCard() {
      return this.flashCard;
  }
  
  public void setFlashCard(FlashCard flashCard) {
      this.flashCard = flashCard;
  }
  
  public void validate() {
      logger.debug("Entering validate()");
  
      if ( flashCard.getQuestion().length() == 0 ){
          addFieldError("flashCard.question", getText("error.flashcard.question"));
      }
  
      if ( flashCard.getAnswer().length() == 0 ) {
          addFieldError("flashCard.answer", getText("error.flashcard.answer"));
      }       
  }
  
  public String saveOrUpdate() {
      logger.debug("Entering saveOrUpdate()");
  
      // assume we'll fail
      boolean result = false;
  
      // are we creating a New Flash Card or Updating and existing one
      // for now, let's assume we are creating a New Flash Card
      boolean newFlashCard = true;
  
      // if this is an Update of an existing Flash CArd then we'll have a Flash Card Id other than 0 
      if (this.flashCard.getFlashCardId() != 0) {
          newFlashCard = false;
      }
  
      try {
          result = fcPersister.saveOrUpdateFlashCard(this.flashCard, session);
  
          // did we save a new FlashCard successfully?
          if (result == true &amp;&amp; newFlashCard) {
              logger.debug("Flash Card created successfully");
  
              this.addActionMessage(getText("actionmessage.flashcard.created"));
          }
          // did we update an existing Flash Card successfully?
          else if (result == true &amp;&amp; newFlashCard == false) {
              logger.debug("Flash Card updated successfully");
  
              this.addActionMessage(getText("actionmessage.flashcard.updated"));                  
          } 
          // such a failure
          else {
              logger.error("unable to create or update FlashCard");
              return "error";
          }
          return "success";
  
      } catch (Exception e) {
          logger.error("Exception in createFlashCard():", e);
  
          return "error";
      }
  }
  
  
  @Override
  public FlashCard getModel() {
      return this.flashCard;
  }
  @Override
  public void setSession(Map&lt;String, Object&gt; httpSession) {
      this.httpSession = httpSession;
  
  }
  @Override
  public void prepare() throws Exception {
      logger.debug("Entering prepare()");
  
      // get a handle to a Hibernate session
      session = getHibernateSession();
  
      // get a handle to the FlashCard persistance utility class 
      fcPersister = new FlashCardPersister();
  }
  
  }
  </code></pre>
  
  <p>And lastly here's the JSP</p>
  
  <pre><code>&lt;%@page import="com.opensymphony.xwork2.ActionContext"%&gt;
  &lt;%@page import="com.opensymphony.xwork2.ActionSupport"%&gt;
  
  &lt;%@ page contentType="text/html; charset=UTF-8"%&gt;
  &lt;%@ taglib prefix="s" uri="/struts-tags"%&gt;
  &lt;%@ taglib prefix="sjr" uri="/struts-jquery-richtext-tags"%&gt;
  
  &lt;h3&gt;&lt;s:text name="label.flashcard.title"/&gt;&lt;/h3&gt;
  
  &lt;s:actionerror theme="jquery" /&gt;
  &lt;s:actionmessage theme="jquery"/&gt;
  &lt;s:fielderror theme="jquery"/&gt;
  
  &lt;s:form action="saveOrUpdate" method="post"&gt;
      &lt;s:hidden name="flashCard.flashCardId" /&gt;
      &lt;s:textfield name="flashCard.question" key="label.flashcard.question" size="66" /&gt;
      &lt;sjr:tinymce 
          id="flashCard.answer" 
          name="flashCard.answer" 
          key="label.flashcard.answer"
          rows="20" 
          cols="50" 
          editorTheme="simple"
      /&gt;
      &lt;s:textfield name="flashCard.links.url" key="label.flashcard.link" size="66" /&gt;
      &lt;tr&gt;
          &lt;td&gt;
              &lt;s:submit label="label.flashcard.submit" align="center" theme="simple" /&gt;
          &lt;/td&gt;
          &lt;td&gt;
              &lt;s:submit key="label.flashcard.cancel" name="redirectAction:list" theme="simple"  /&gt;
          &lt;/td&gt;
      &lt;/tr&gt;
  &lt;/s:form&gt;
  
  &lt;%((ActionSupport)ActionContext.getContext().getActionInvocation().getAction()).clearErrorsAndMessages();%&gt;
  </code></pre>