Click
  1. Click
  2. CLK-63

CayenneForm getDataObject might create new data object on each call

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None

      Description

      Issue was mentioned here :

      http://article.gmane.org/gmane.comp.web.click.user/114

      To recap : each call to getDataObject would create and register a new data object instance, if that object is not persisted in the database.
      For already persisted object there is no problem.

      What I would like todo is the following :

      Department dep = (Department) cayenneForm.getDataObject(); //<--this call creates and registes new data object
      dep.setPerson(person);

      //because saveChanges() also makes a call to getDataObject(), another department is created and registered with cayenne,
      //and we end up with two database entries.
      cayenneForm.saveChanges();

      Kind Regards,

      bob

        Activity

        Henri Yandell made changes -
        Project Import Fri Mar 20 14:11:32 PDT 2009 [ 1237583492744 ]
        Malcolm Edgar made changes -
        Status Resolved [ 5 ] Closed [ 6 ]
        Malcolm Edgar made changes -
        Type Improvement [ 4 ] Bug [ 1 ]
        Malcolm Edgar made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Hide
        Malcolm Edgar added a comment -

        Fix checked into CVS. Will made available in release 0.19

        Show
        Malcolm Edgar added a comment - Fix checked into CVS. Will made available in release 0.19
        Hide
        Christian Essl added a comment -

        Hi Bob,

        Concerning the TestCase unfortunately I don't know much about Cayenne so I can't say anything about this side. However for the click side it should be no problem. If you downlaod the files from CLK63 than I can imagine it somekind likethe following (usinig the deparment example of the CayenneForm api-doc):

        public class CayenneTestCase extends ClickTestCase{

        MockContextBuilder _builder = new MockContextBuilder();

        public CayenneTestCase()

        { super(); _builder.restartServlet(); }

        @Override
        protected void setUp() throws Exception

        { //setup the threadlocal Cayenne DataContext }

        public void testFormOnGet()

        { //first setup the form CayenneForm form = new CayenneForm("form",Department.class); TextField departmentName = new TextField("name", "Department Name", 35); TextArea departmentDesc = new TextArea("description", "Description", 35, 2); form.add(departmentName); form.add(departmentDesc); //than init the form MockContext ctxt = _builder.create(); ctxt.initControl(form); //do the testing of the form form.setDataObject(...); assertEquals("Finance",departmentName.getValue()); assertEquals("A big dep",departmentDesc.getValue()); }

        public void testFormPost()

        { //setup the form again CayenneForm form = new CayenneForm("form",Department.class); TextField departmentName = new TextField("name", "Department Name", 35); TextArea departmentDesc = new TextArea("description", "Description", 35, 2); form.add(departmentName); form.add(departmentDesc); //than the context but this time post MockContext ctxt = _builder.create(true); //than we set first the post requestParams //hidden fields of cayenne form ctxt.setRequestParam("DOPK", "12"); //primary key of the DataObject ctxt.setRequestParam("DOCLASS", Department.class.toString()); //the fields request params ctxt.setRequestCtrl(departmentDesc, "New description"); ctxt.setRequestCtrl(departmentName, "Marketing"); //the form to submit ctxt.setRequestForm(form); //process the form ctxt.initControl(form); form.onProcess(); //now assert what ever needed using the form assertTrue(form.isValid()); form.saveChanges(); . }

        }

        I think this should work, but I have not tried it because as said I do currently not use Cayenne. I'll take a look now. Hope that helps.

        Christian

        Show
        Christian Essl added a comment - Hi Bob, Concerning the TestCase unfortunately I don't know much about Cayenne so I can't say anything about this side. However for the click side it should be no problem. If you downlaod the files from CLK63 than I can imagine it somekind likethe following (usinig the deparment example of the CayenneForm api-doc): public class CayenneTestCase extends ClickTestCase{ MockContextBuilder _builder = new MockContextBuilder(); public CayenneTestCase() { super(); _builder.restartServlet(); } @Override protected void setUp() throws Exception { //setup the threadlocal Cayenne DataContext } public void testFormOnGet() { //first setup the form CayenneForm form = new CayenneForm("form",Department.class); TextField departmentName = new TextField("name", "Department Name", 35); TextArea departmentDesc = new TextArea("description", "Description", 35, 2); form.add(departmentName); form.add(departmentDesc); //than init the form MockContext ctxt = _builder.create(); ctxt.initControl(form); //do the testing of the form form.setDataObject(...); assertEquals("Finance",departmentName.getValue()); assertEquals("A big dep",departmentDesc.getValue()); } public void testFormPost() { //setup the form again CayenneForm form = new CayenneForm("form",Department.class); TextField departmentName = new TextField("name", "Department Name", 35); TextArea departmentDesc = new TextArea("description", "Description", 35, 2); form.add(departmentName); form.add(departmentDesc); //than the context but this time post MockContext ctxt = _builder.create(true); //than we set first the post requestParams //hidden fields of cayenne form ctxt.setRequestParam("DOPK", "12"); //primary key of the DataObject ctxt.setRequestParam("DOCLASS", Department.class.toString()); //the fields request params ctxt.setRequestCtrl(departmentDesc, "New description"); ctxt.setRequestCtrl(departmentName, "Marketing"); //the form to submit ctxt.setRequestForm(form); //process the form ctxt.initControl(form); form.onProcess(); //now assert what ever needed using the form assertTrue(form.isValid()); form.saveChanges(); . } } I think this should work, but I have not tried it because as said I do currently not use Cayenne. I'll take a look now. Hope that helps. Christian
        Hide
        Malcolm Edgar added a comment -

        Hi Bob,

        thanks for the patch.

        regards Malcolm Edgar

        Show
        Malcolm Edgar added a comment - Hi Bob, thanks for the patch. regards Malcolm Edgar
        Bob Schellink made changes -
        Field Original Value New Value
        Attachment CayenneForm.java.patch [ 10052 ]
        Hide
        Bob Schellink added a comment -

        Attached is my workaround/patch.

        Basically just changed the scope of the dataObject variable, from local to member scope. Thus dataObject now serves as a member scoped variable (cache), which is returned for subsequent calls to getDataObject. The change only applies to data object that is not already persisted in the database.

        Perhaps getDataObject() should return the cached object for persisted objects as well? Meaning subsequent calls to the method should just return the cache, without further processing.

        I am pretty new to web side development, so might be missing something obvious

        I would attach a test case, but am not sure how Click is to be tested against Cayenne. I see one of the other developers is busy with a click unit testing framework. Perhaps that could be used to test Cayenne integration too.

        Regards,

        bob

        Show
        Bob Schellink added a comment - Attached is my workaround/patch. Basically just changed the scope of the dataObject variable, from local to member scope. Thus dataObject now serves as a member scoped variable (cache), which is returned for subsequent calls to getDataObject. The change only applies to data object that is not already persisted in the database. Perhaps getDataObject() should return the cached object for persisted objects as well? Meaning subsequent calls to the method should just return the cache, without further processing. I am pretty new to web side development, so might be missing something obvious I would attach a test case, but am not sure how Click is to be tested against Cayenne. I see one of the other developers is busy with a click unit testing framework. Perhaps that could be used to test Cayenne integration too. Regards, bob
        Bob Schellink created issue -

          People

          • Assignee:
            Malcolm Edgar
            Reporter:
            Bob Schellink
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development