0 Replies Latest reply on May 19, 2011 7:04 AM by dangerousbeans

    Validation clearing non persisted entities from all many-to-many relationships

      Have been stuck on this for a while, can't work out what's going wrong, any help would be awesome.

      My requirement is that when I create a new DeDestination entity, I populate it was a number of DeDestinationTag entities in a collection.
      The user then sees the fields for a DeDestination, followed by two fields for each DeDestinationTag. The whole arrangement is as of yet not persisted.

      This works fine except in some validation situations:


      If required fields are missing on both the main object and from at least one of the DeDestinationTag objects, the on save fails validation and returns the page correctly with all the filled in values so far intact. If, however, all the DeDestinationTag fields are filled in and there is a validation error on the main entity, all the DeDestinationTag fields will be WIPED which is making me SAD. :(

      I cannot see the values being set on the non persisted entities, but they do seem to go through fine so long as there is no validation.


      Key code parts:

      ============================
      DeDestination.java
      ============================
      [...]
      @Entity
      @Table(name = "de_destination")
      public class DeDestination implements java.io.Serializable
      {
           private static final long serialVersionUID = -7796513739726297533L;
           
           // Attributes
      [...]
              // Tags
           private List<DeDestinationTag> deTagForDestination = new ArrayList<DeDestinationTag>();

              @OneToMany(mappedBy = "destination", cascade=CascadeType.REMOVE)
           public List<DeDestinationTag> getDeTagForDestination()
           {
                return deTagForDestination;
           }
           public void setDeTagForDestination(List<DeDestinationTag> deTagForDestination)
           {
                this.deTagForDestination = deTagForDestination;
           }
      [...]


      ============================
      DeDestinationTag.java
      ============================


      @Entity
      @Table(name = "de_destination_tag")
      public class DeDestinationTag implements java.io.Serializable
      {
              // Attributes
           private int id;

              private DeDestination destination;
           private DeTagInfo tag;
           private DeTagScale score;
           private String why;
           private String other;

      [...]

              @ManyToOne
           @JoinColumn(name = "score", nullable = false)
           @NotNull
           public DeTagScale getScore() {
                return score;
           }
           public void setScore(DeTagScale score) {
                this.score = score;
           }

      [...]
      (the rest are similar)


      ============================
      Create instance part of DeDestinationHome
      ============================
      [...]
              @Override
           protected DeDestination createInstance()
           {
                DeDestination deDestination = new DeDestination();

                deDestination.setFormCompleted(false);

                // Add the minimum required rating tags to this new accommodation
                   this.addTags(deDestination);
                
                return deDestination;
           }
      [...]

      ===============================
      DeDestinationEdit.page.xml
      ===============================
      <page xmlns="http://jboss.com/products/seam/pages"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd"
            no-conversation-view-id="/DeDestinationList.xhtml"
            login-required="true">

         <begin-conversation join="true" flush-mode="MANUAL"/>
      [...]


      ===============================
      DeDestinationEdit.xhtml
      ===============================
      [...]
                               <ui:repeat var="_tag_rating" value="#{deDestinationHome.instance.deTagForDestination}">
                            
                                         <a4j:region renderRegionOnly="true">
                                              <s:decorate id="field" template="layout/edit.xhtml">
                                                   
                                                   <h:selectOneMenu
                                                        value="#{_tag_rating.score}"
                                                        required="#{_tag_rating.tag.required}">
                                                        <s:selectItems var="_deTagScale"
                                                             value="#deTagManager.getTagScale(_tag_rating.tag.scale)}"
                                                             label="#{_deTagScale.value} #{_deTagScale.label}"
                                                             noSelectionLabel="Select..." />
                                                        <s:convertEntity />
                                                        <a4j:support event="onchange" eventsQueue="validationQueue"
                                                             reRender="field" bypassUpdates="false"
                                                             ajaxSingle="true">
                                                             <s:conversationId />
                                                        </a4j:support>
                                                   </h:selectOneMenu>
      [...]