Announcement

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

    TreeGrid.invalidateCache() reports a collision when I refresh?

    SmartClient Version: v9.1p_2014-09-09/PowerEdition Deployment (built 2014-09-09)
    GWT 2.6.1
    IE-11

    I have a TreeGrid configured as follows:
    Code:
                treeGrid.setAutoFetchData(Boolean.TRUE);
                treeGrid.setLoadDataOnDemand(Boolean.TRUE);
                treeGrid.setAlwaysShowOpener(Boolean.TRUE);
    I am changing the depth of the Tree by changing external data structures and calling TreeGrid.invalidateCache() to trigger a refresh. My understanding is when a Grid is set to auto-fetch, you cannot do a manual fetch via Grid.fetchCriteria(criteria), as referenced in the Javadoc under ListGrid.fetchCriteria(criteria). So the only other way I assume to trigger a manual refresh is to do a Grid.invalidateCache() which does trigger a refresh (DSOperationType.FETCH), great.

    When I get down to 1 record in the Tree and do my refresh, I am seeing an error about a collision in IDs in the tree:
    Code:
    ERROR: 15:11:16.009:TMR2:WARN:ResultTree:isc_ResultTree_0 (created by: isc_PivotTableGrid_5_0):Adding node to tree with id property set to:1. A node with this ID is already present in this Tree - that node will be replaced. Note that this warning may be disabled by setting the reportCollisions attribute to false.
    com.smartgwt.client.core.JsObject$SGWT_WARN: 15:11:16.009:TMR2:WARN:ResultTree:isc_ResultTree_0 (created by: isc_PivotTableGrid_5_0):Adding node to tree with id property set to:1. A node with this ID is already present in this Tree - that node will be replaced. Note that this warning may be disabled by setting the reportCollisions attribute to false.
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    	at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    	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:293)
    	at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547)
    	at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
    	at java.lang.Thread.run(Thread.java:744)
    And the Grid goes blank, I lose that original record and the updated record that I sent back during the refresh (FETCH)? The Grid did not complain about ID collisions when there are more than 1 record in the Grid?
    Last edited by JLivermore; 16 Sep 2014, 11:37.

    #2
    My understanding is when a Grid is set to auto-fetch, you cannot do a manual fetch via Grid.fetchCriteria(criteria), as referenced in the Javadoc under ListGrid.fetchCriteria(criteria). So the only other way I assume to trigger a manual refresh is to do a Grid.invalidateCache() which does trigger a refresh, great.
    This isn't true and isn't what the docs say.. autoFetchData causes an automatic fetch at initial draw. If you enable autoFetchData then manually call fetchData() right before or after draw then you will at best create an unnecessary duplicate fetch, at worst, end up with the wrong data showing. The latter effect would happen, if you, for example, set grid.initialCriteria, but then called fetchData() with no criteria immediately after the autoFetch kicked off.

    Since autoFetchData applies only at initial draw, this situation never arises again from then on, and you can and should use fetchData() to apply new criteria.

    As far as the warning about ID collisions (it's a warning not an error), we don't have enough information to try and reproduce that or your subsequent problem with the data going blank. We *might* be able to help if you post the usual required information (RPC tab contents, etc) but if you think it's a framework issue, what always works is a minimal, ready-to-run test case demonstrating the issue.

    Comment


      #3
      Originally posted by Isomorphic View Post
      This isn't true and isn't what the docs say.. autoFetchData causes an automatic fetch at initial draw. If you enable autoFetchData then manually call fetchData() right before or after draw then you will at best create an unnecessary duplicate fetch, at worst, end up with the wrong data showing. The latter effect would happen, if you, for example, set grid.initialCriteria, but then called fetchData() with no criteria immediately after the autoFetch kicked off.

      Since autoFetchData applies only at initial draw, this situation never arises again from then on, and you can and should use fetchData() to apply new criteria.
      OK, thank you for clarifying autoFetchData for me, so the only purpose that serves is the first time the Grid is drawn? After that automatic-fetch is complete and the grid redraws that feature is disabled or set to false?

      Comment


        #4
        It's neither disabled nor set to false, but it has no further effect.

        Comment


          #5
          In the RPC tab I am seeing two DSRequests when I was expecting one. The second one contains oldValues? OK, that second DSRequest is coming from Grid.invalidateCache().
          Last edited by JLivermore; 16 Sep 2014, 14:29.

          Comment


            #6
            OK.. let us know when you have more info, and we can comment.

            Comment


              #7
              My TreeGrid is backed by a Dynamic DataSource and is configured as follows:
              Code:
                          treeGrid.setAutoFetchData(Boolean.TRUE);
                          treeGrid.setLoadDataOnDemand(Boolean.TRUE);
                          treeGrid.setAlwaysShowOpener(Boolean.TRUE);
                          treeGrid.setDataSource(treeDataSource);
              When I do a TreeGrid.invalidateCache() it triggers a FETCH. Interestingly, the Grid will remember the node expansions and recreate the entire tree with multiple FETCHes.

              I have a case where I need to recreate the tree in 1 shot, not by multiple FETCHes. Is there a way to invalidate the cache (with out triggering the automatic FETCHes) and do my own custom single FETCH to refresh the tree?
              Last edited by JLivermore; 17 Sep 2014, 11:56.

              Comment


                #8
                If you see a fetch for root, you are allowed to return however much of the tree you want to (see Tree Data Binding overview), so that's one way of handling this.

                Another would be to fetch the nodes, create a ResultTree containing them, and provide it to the TreeGrid via setData().

                Comment


                  #9
                  So in the root fetch, I return my entire tree, and then I shouldn't see the fetches for the nodes that were expanded, because the data is already there. That sounds good.

                  Comment


                    #10
                    Right, although it doesn't have to be the entire tree, it can be any subset of it.

                    It's pretty common to return the top two levels, or whichever nodes are most frequently accessed, and leave the rest to be fetched by load on demand.

                    Comment


                      #11
                      Is there a way to identify a DSRequest for the TreeGrid.invalidateCache() call?

                      Comment


                        #12
                        The criteria would be designed to select the children under root, same as the initial request to populate the tree - is that what you need?

                        Comment


                          #13
                          No, not the initial request, but after I make a call to TreeGrid.invalidateCache()? Let me ask another way, inside my RequestTransformer for the TreeGrid, is there a way to inspect the DSRequest to identify it is the root node request for the FETCH being performed to update the cache other than looking for the value of the root node? Because that happens upon the initial request. That is what I want to avoid. Otherwise, I can just add state logic to the class for the initial root node request.

                          Comment


                            #14
                            There's no logical distinction between the request issued initially, and the request issued because you called invalidateCache() - it has the same criteria, same parentNode, etc.

                            If you want to distinguish between what API you just called (we're not sure why ..) you could of course just set some static boolean property that your RequestTransformer can check.

                            Comment


                              #15
                              We do have a case where if our data set is small enough, we would want to return the entire loaded tree on the first FETCH for the update cache event (TreeGrid.invalidateCahce()).

                              Comment

                              Working...
                              X