Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    ListGrid editing problems

    Using SmartGWT 3.0 on Firefox 7.0...

    I've been trying to create a simple ListGrid based on the "Edit By Cell" example in the SmartGWT Showcase. The data in my DataSource is programmatically generated, and I'm using a custom subclass of Record to represent the data.

    All the rendering works fine, including the value of the attribute that I've marked as the primary key. The problem starts when I attempt to edit a cell within a row. I get the following stack trace:

    Code:
    ERROR: 19:21:42.490:TMR4:WARN:Log:findByKeys: passed record does not have a value for key field 'pk'. com.smartgwt.client.core.JsObject$SGWT_WARN: 19:21:42.490:TMR4:WARN:Log:findByKeys: passed record does not have a value for key field 'pk'
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    	at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:105)
    	at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    	at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
    	at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:292)
    	at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:546)
    	at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
    	at java.lang.Thread.run(Thread.java:680)
    ERROR: 19:21:42.490:TMR4:WARN:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):Update operation - submitted record with primary key value[s]:{pk: 6} returned with modified primary key:{}. This may indicate bad server logic. Updating cache to reflect new primary key.. com.smartgwt.client.core.JsObject$SGWT_WARN: 19:21:42.490:TMR4:WARN:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):Update operation - submitted record with primary key value[s]:{pk: 6} returned with modified primary key:{}. This may indicate bad server logic. Updating cache to reflect new primary key.
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    	at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:105)
    	at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    	at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
    	at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:292)
    	at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:546)
    	at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
    	at java.lang.Thread.run(Thread.java:680)

    I don't understand why this is, because I set the primaryKey attribute in the ListGrid (a unique-by-row, ever-increasing integer value). I've also verified that the attribute 'pk' is set in the Record. I did this via setting an EditCompleteHandler on the ListGrid, and then calling a custom method that dumps the attribute values out by attribute name. The 'pk' attribute is clearly set for each record. Also, in the above CODE example, you can see that it knows that 'pk 6' has been edited, which adds to the confusion.

    Also, when I edit a field, the new value displays for a moment, but the row eventually disappears from the ListGrid. I've called "setCanRemoveRecords(false)" on my ListGrid, but that hasn't helped.

    Is there an example in the Showcase that demonstrates editing on Record subclasses that are not initially populated from an XML file?

    Somewhat related question: Is the "best practice" for a ListGrid to call setDataSource only once during the ListGrid's lifespan, and then cause that data source's content to change one way or another, OR, can new data sources be instantiated at will, each time being followed by a call to "setDataSource"?

    My application involves some server-side processing where it's natural to create a new data source upon the completion of that work, and then to set the new data source to the ListGrid thereafter. However, I've noticed that the fields in the table need to be reset after each "setDataSource" call, hence my "best practices" question.

    Is there an example that shows a subclass of DataSource where various methods are overriden that demonstrate the events that happen when a Record is edited?

    #2
    I don't know if this will help you but we also have an editable ListGrid and its ListDataSource has this field (code is from ListDataSource constructor):

    Code:
    // As shown in a Showcase example. This generates a sequence of numbers.
    DataSourceIntegerField primaryKey = new DataSourceIntegerField("pk");  
    primaryKey.setHidden(true);  
    primaryKey.setPrimaryKey(true);  
    
    setFields(primaryKey, ...other fields...);
    The ListGrid doesn't need to add this field as a ListGridField.
    Last edited by ferranmc; 30 Dec 2011, 04:59.

    Comment


      #3
      Thanks ferranmc... I have the same calls in my code, and indeed, it was only upon adding that code that any of the editing behaviors in the table began to sort of work. But something's still fundamentally wrong.

      I commented out the "setHidden" call just to be able to verify that the 'pk' attribute in the Record was actually set, contrary to the error messages, and indeed I can see the values in the Grid. The only thing I can think of is that there is some OTHER instance involved in the editing process and that the 'pk' value is not being copied into that instance.

      Comment


        #4
        You mention that you've subclasses Record, presumably to add your own getters and setters. See docs for Record - if you've done this, you still need to call setAttribute() to put values in the Record that grids and other components will see.

        Comment


          #5
          I've called "setAttribute" for all of the attributes, including the one designated as the primary key. I can see all of the attributes for each Record in the ListGrid. The Exceptions are only thrown when I initiate an edit.

          I've only enabled editing for two fields, an Integer field ( not the primary key field) and a Boolean field, via a checkbox cell. The error gets generated upon attempting to edit either one. Following the edit attempt, the Record disappears from the ListGrid.

          Comment


            #6
            If you look again at the two Exceptions, you'll see that at the time of the second one, the primary key value is known ('pk' value 6). At the time of the first Exception, why is the 'pk' value supposedly not set?

            Comment


              #7
              Could you post a standalone example that reproduces the problem? That way I can compare it to my code.

              Comment


                #8
                Seconded!
                We're happy to take a look at this issue but we don't have enough information to know what's happening. If you can post a standalone example that we can run to reproduce the problem we'll be able to get this resolved.

                Comment


                  #9
                  I've got a simple class that creates a table with an editable column. When you change the person's age, the row disappears. I've seen some references in the forums to this problem, but I'm not using "filters" and can't see why this behavior would occur in my case.

                  Regarding the Exceptions that I describe in earlier posts, I'm not seeing those, but I will continue to build out this example to more closely represent my actual production code. I'll make further posts when I learn more.

                  One important difference between this and my production code is my need to completely change the data and table structure (number of columns and rows) upon a variety of user actions. I'm still seeking guidance on the "best practice" for that. Two possible choices:
                  1. Allow the ListGrid to retain the reference to the same DataSource instance at all times, never call "setDataSource" more than once, and manage all data changes within that single DataSource instance.
                  2. Create a new DataSource each time and attempt to reset it into the ListGrid.

                  My production data structures (starting with the ListGridRecord subclass) allow for the dynamic behavior described above, but I am then forced to regenerate the DataSourceField and ListGridField collections accordingly -- not a big deal programmatically -- but perhaps something in that code is ultimately the cause of the Exceptions I mention in the other posts.

                  Note, however, that the "disappearing row" problem is also present in my production code.


                  Code:
                  public class ListGridEditPanel implements EntryPoint
                  {
                      private ListGrid d_grid;
                  
                      private static final String FIELDNAME_KEY = "key";
                      private static final String FIELDNAME_NAME = "name";
                      private static final String FIELDNAME_DEPT = "dept";
                      private static final String FIELDNAME_AGE = "age";
                  
                      private static final int NUM_COLS=4;
                  
                      private static final int COL_KEY = 0;
                      private static final int COL_DEPT = 1;
                      private static final int COL_NAME = 2;
                      private static final int COL_AGE = 3;
                  
                      public class DataModel extends DataSource
                      {
                          private ArrayList<MyRecord> d_data = new ArrayList<MyRecord>();
                  
                          public DataModel()
                          {
                              int key = 1;
                              d_data.add(new MyRecord(key++,"John","Sales",40));
                              d_data.add(new MyRecord(key++,"Frank","Sales",42));
                              d_data.add(new MyRecord(key++,"Bill","Accounting",38));
                              d_data.add(new MyRecord(key++,"Charlie","Accounting",39));
                  
                              DataSourceField[] fields = new DataSourceField[key-1];
                  
                              fields[COL_KEY] = new DataSourceIntegerField(FIELDNAME_KEY,"keyTitle");
                              fields[COL_KEY].setPrimaryKey(true);
                              fields[COL_KEY].setHidden(true);
                  
                              fields[COL_DEPT] = new DataSourceTextField(FIELDNAME_DEPT,"deptTitle");
                              fields[COL_NAME] = new DataSourceTextField(FIELDNAME_NAME,"nameTitle");
                  
                              fields[COL_AGE] = new DataSourceIntegerField(FIELDNAME_AGE,"ageTitle");
                              fields[COL_AGE].setCanEdit(true);
                  
                              setFields(fields);
                  
                  
                              setClientOnly(true);
                              setCacheData(d_data.toArray(new MyRecord[d_data.size()]));
                              setCacheAllData(true);
                          }
                      }
                  
                      public static class MyRecord extends ListGridRecord
                      {
                          private int d_keyValue;
                          private String d_name;
                          private String d_dept;
                          private int    d_age;
                  
                          public MyRecord(int keyValue, String name, String dept,int age)
                          {
                              d_keyValue = keyValue;
                              d_name = name;
                              d_dept = dept;
                              d_age = age;
                  
                              setAttribute(FIELDNAME_KEY,keyValue);
                              setAttribute(FIELDNAME_NAME,name);
                              setAttribute(FIELDNAME_DEPT,dept);
                              setAttribute(FIELDNAME_AGE,age);
                          }
                      }
                  
                      public void onModuleLoad()
                      {
                          d_grid = new ListGrid();
                          d_grid.setWidth(500);
                          d_grid.setHeight(400);
                  
                  
                          ListGridField[] fields = new ListGridField[NUM_COLS];
                  
                          fields[COL_KEY] = new ListGridField(FIELDNAME_KEY,"Key");
                          fields[COL_KEY].setHidden(true);
                          
                          fields[COL_NAME] = new ListGridField(FIELDNAME_NAME,"Name");
                          fields[COL_DEPT] = new ListGridField(FIELDNAME_DEPT,"Dept");
                          fields[COL_AGE] = new ListGridField(FIELDNAME_AGE,"Age (EDIT)");
                  
                          d_grid.setCanRemoveRecords(false);
                          d_grid.setEditByCell(true);
                          d_grid.setFields(fields);
                          d_grid.setAutoFetchData(true);
                          d_grid.setShowAllRecords(true);
                  
                  
                          DataModel dm = new DataModel();
                  
                          d_grid.setDataSource(dm);
                  
                          Canvas canvas = new Canvas();
                          canvas.addChild(d_grid);
                          canvas.draw();
                      }
                  }

                  Comment


                    #10
                    I think I had to set the primary key name to "pk", although I am not sure.

                    Try that: FIELDNAME_KEY = "pk"

                    Also, it is not necessary to add the primary key as a ListGridField as you do here (but I suppose it doesn't hurt):

                    fields[COL_KEY] = new ListGridField(FIELDNAME_KEY,"Key");
                    fields[COL_KEY].setHidden(true);
                    Last edited by ferranmc; 4 Jan 2012, 01:54.

                    Comment


                      #11
                      ferranmc, the value of the String used to specify the primaryKey field does not matter. All that matters is that it's used consistently.

                      Not specifying a primaryKey field in the ListGridField array creates other problems.

                      Regarding the Exceptions thrown in the production code, I realized that they were in this test case as well, but were in a different debugger tab (I use JetBrains' IntelliJ).

                      Code:
                      ERROR: 10:04:12.442:TMR5:WARN:Log:findByKeys: passed record does not have a value for key field 'key'. com.smartgwt.client.core.JsObject$SGWT_WARN: 10:04:12.442:TMR5:WARN:Log:findByKeys: passed record does not have a value for key field 'key'
                      	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
                      	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
                      	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
                      	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
                      	at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:105)
                      	at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
                      	at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
                      	at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:292)
                      	at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:546)
                      	at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
                      	at java.lang.Thread.run(Thread.java:680)
                      ERROR: 10:04:12.443:TMR5:WARN:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):Update operation - submitted record with primary key value[s]:{key: 3} returned with modified primary key:{}. This may indicate bad server logic. Updating cache to reflect new primary key.. com.smartgwt.client.core.JsObject$SGWT_WARN: 10:04:12.443:TMR5:WARN:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):Update operation - submitted record with primary key value[s]:{key: 3} returned with modified primary key:{}. This may indicate bad server logic. Updating cache to reflect new primary key.
                      	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
                      	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
                      	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
                      	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
                      	at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:105)
                      	at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
                      	at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
                      	at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:292)
                      	at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:546)
                      	at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
                      	at java.lang.Thread.run(Thread.java:680)
                      Upon seeing those Exceptions, the edited row disappears. Note that the 'key' field has a value of '3', referring to the third row in the table that I attempted to edit.

                      I'm eager to hear from Isomorphic.

                      Comment


                        #12
                        These exceptions are pretty self-explanatory, right? They indicate that you did an update operation, and the returned data had no primary key value.

                        Comment


                          #13
                          Sorry to say, it's not at all self-explanatory, since all of my ListGridRecords are given primary key values (as seen in the code).

                          1. "returned data" is coming from where? The entire program is in the previous post. The Exceptions happen in response to a user-initiated action. Is there some kind of "copy construction" going on somewhere, where all the attributes of one Record are being propagated to another Record with the EXCEPTION of the primary key field?
                          2. Where in the code should I handle data that is being "returned"?
                          3. Where in the documentation is this idiom described? My example is not dramatically different than http://www.smartclient.com/smartgwt/...d_editing_cell Where in that program is "returned data" being handled? I don't see any type of Editor "handlers" or "callbacks" there, but I could understand the need for such a thing.
                          4. Under what types of use cases would I want an edited row to disappear from my table?
                          5. Do I need to be using a subclass of RestDataSource?
                          Last edited by dzarras; 4 Jan 2012, 19:22.

                          Comment


                            #14
                            You previously said that the standalone sample does not reproduce the problems you are reporting. So can you indicate now if it reproduces any of the problems, and if so, which ones?

                            Note one immediate problem with that code is that it sets both clientOnly and cacheData and cacheAllData - these settings do not make sense together.

                            About your questions: see the QuickStart Guide, Data Integration chapter, and really read through it, don't skip key links to eg the ResultSet class. Likewise, read the Grid Editing overview.

                            Finally, realize that a clientOnly DataSource fully simulates a remote DataSource, so all of the above applies even though there is no data being "returned" from a remote source.

                            And for completeness: you would want a row to disappear from your table if it no longer matched the search criteria after having been changed. But read the ResultSet docs mentioned above for background.

                            Comment


                              #15
                              Thanks for the more comprehensive reply. To be clear though, in a previous post I clarified that the code example DOES replicate the production problems. Since I took the time to write it at your request, can you please run it and see what happens?

                              I think a lot of my confusion at this point stems from the fact that the simple editing examples in the Showcase, which I used as a starting point, don't make use of ResultSet, they don't override any methods in DataSource, and they don't register any custom editing handlers. Yet when a person changes a "population" number, for example, the change sticks and the row does not disappear. I'm also not making use of searching and/or filtering, so the disappearing row behavior should not seem to apply, either.
                              Last edited by dzarras; 5 Jan 2012, 06:00.

                              Comment

                              Working...
                              X