I solved the problem. The collection filled with data by Hibernate was not sorted. After adding order-by into the set definition in my Party.hbm.xml all works fine:

        <class name="net.expertys.model.Party" table="Party">
                <id name="partyID" column="partyID" type="long">
                        <generator class="increment"/>
                </id>
<set name="addresses" inverse="true" cascade="all,delete-orphan" order-by="nameAddressID">
                        <key column="partyID"/>
                        <one-to-many class="net.expertys.model.NameAddress"/>
                </set>
        </class>

I use the database id nameAddressID to identify the repeater rows, no extra ids are necessary.

Barbara

On 8 Jun, 2007, at 10:46 pm, Barbara Slupik wrote:

Hello

I am trying to add a row in a CForms repeater but the new row replaces some of the old data in the collection.

I am using Cocoon-2.1.10 with Hibernate-3.2, Spring-2.0.4 and MySQL-5.0.37. The repeater rows are loaded from the database and displayed correctly on the screen. When I try to add a new row sometimes it works and after the form is submited my collection contains all rows from the repeater. But most times the last object in the original collection gets replaced by the new repeater row and a null object is added to the collection. I think that the problem might be with the row id. I was experimenting with it but cannot make it work.

Below are some parts of the code. Please can anyone offer some help or suggestions for how to make it work.

Barbara

Beans
==========
// Party is the main item on the form
public class Party {
...
        private Long partyID;
        private Collection addresses=new ArrayList();
...
        public void setAddresses(Collection addresses) {
        this.addresses=addresses;
                int i=0;
                Iterator it=addresses.iterator();
                while (it.hasNext()) {
                        NameAddress address=(NameAddress)it.next();
                        address.setId(i);
                        i=i+1;
                }

        }
        public void addAddress(NameAddress address) {
                //address.setId(addresses.size());
                addresses.add(address);
                address.setParty(this);
        }
}

// NameAddress are the items which appear in the repeater, nameAddressID is the id from the database
public class NameAddress {
        private int id;
        private Long nameAddressID;
        private Long partyID;
...
}

Binding
===========

  <fb:repeater id="addresses" parent-path="." row-path="addresses">
    <fb:identity>
      <fb:value id="id" path="id"/>
      <!--<fb:value id="nameAddressID" path="nameAddressID"/>-->
    </fb:identity>
                <!-- executed on updates AND right after the insert -->
    <fb:on-bind>
      <fb:javascript id="id" path="id" direction="save">
        <fb:save-form>
          if (widget.getValue()==null) {
                                                var form = widget.getForm();
                                                var count = 
form.getAttribute("addressCounter");
                                                jxpathPointer.setValue(count);
                                                
form.setAttribute("addressCounter", count+1);
                                        }
        </fb:save-form>
      </fb:javascript>
      <!--<fb:value id="nameAddressID" path="nameAddressID"/>-->
...
    </fb:on-bind>
                <!-- executed in case a row has been deleted -->
    <fb:on-delete-row>
      <fb:delete-node/>
    </fb:on-delete-row>
                <!-- executed in case a new row has been added -->
    <fb:on-insert-row>
<fb:insert-bean classname="net.expertys.model.NameAddress" addmethod="addAddress"/>
    </fb:on-insert-row>
  </fb:repeater>
 ...

Flow
=======

function Party() {
        getApplication();
        var id=cocoon.request.getParameter("id");
        var party=application.readParty(new java.lang.Long(id));
        var formDefinition=cocoon.parameters["form-defn"];
        var formBinding=cocoon.parameters["form-bind"];
        var form=new Form(formDefinition);
        form.setAttribute("addressCounter",party.getAddresses().size());
        form.createBinding(formBinding);
        form.load(party);
        form.showForm("Party-display");
        if (form.isValid) {
                if (id==null) {}
                else {
                        form.save(party);
                        application.saveParty(party);
                        cocoon.sendPage("Party?id="+id);
                }
        }
        else {cocoon.redirectTo("Parties(1)")};
}


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to