Announcement

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

    addRelatedUpdate question

    I have a listGrid which always displays some values depending on some criteria, let's say where field1 == "A".

    If I update one of the records in another component using another datasource, I use addRelatedUpdate() on the server-side. This uses an UPDATE dsResponse for this.
    So let's say I update the record to: field1 = "B" and call addRelatedUpdate().

    Then, the record disappears from the listGrid since it gets an update and the criteria hide records having field1 != "A". This is correct.

    But the other way around is not working:
    I have a record with field = "B". I update the value to "A" somewhere else and call addRelatedUpdate().

    The record is not appearing in the listGrid! Is this the normal behavior? And what can I do to correct this ?

    Using smartGWT 4.1p Power.

    #2
    Reading the docs/forum posts, and after creating a test case, I think this is a bug. Maybe it is related/specific to MSSQL 2014, since we had in the past serious bugs/issues related to this? E.g. http://forums.smartclient.com/showthread.php?t=31159 , or http://forums.smartclient.com/showthread.php?t=28397

    My testcase:

    EntryPoint:
    Code:
    public class TestingModule implements EntryPoint {
    
    	public void onModuleLoad() {
    
    		VLayout vlayout = new VLayout();
    
    		IButton button = new IButton("Click ME");
    		button.addClickHandler(new ClickHandler() {
    
    			@Override
    			public void onClick(ClickEvent event) {
    				new MyWindow3().show();
    			}
    		});
    		vlayout.addMember(button);
    		vlayout.draw();
    	}
    
    }
    MyWindow3.java:
    Code:
    public class MyWindow3 extends Window {
    
    	private final ListGrid lg;
    
    	private final IButton button;
    
    	private Integer actualStatus = 1;
    
    	TextItem idItem;
    
    	public MyWindow3() {
    		setWidth(1050);
    		setHeight(760);
    		setAutoCenter(true);
    		setIsModal(true);
    		setShowModalMask(true);
    		setShowMaximizeButton(true);
    
    		VLayout vlayout = new VLayout(12);
    		vlayout.setPadding(25);
    
    		lg = new ListGrid();
    		lg.setDataSource(DataSource.get("testDatasource"));
    
    		lg.setWidth("100%");
    		lg.setHeight(400);
    		lg.setSortField("f_id");
    
    		lg.setAutoFetchData(false);
    
    		HLayout buttonsLayout = new HLayout(15);
    		buttonsLayout.setHeight(25);
    		buttonsLayout.setAlign(Alignment.LEFT);
    
    		DynamicForm df = new DynamicForm();
    		idItem = new TextItem("id");
    		df.setFields(idItem);
    
    		buttonsLayout.addMember(df);
    
    		button = new IButton("Switch status");
    		button.setWidth(200);
    		button.addClickHandler(new ClickHandler() {
    			@Override
    			public void onClick(ClickEvent event) {
    				onButtonClick();
    			}
    		});
    
    		buttonsLayout.addMember(button);
    
    		vlayout.addMember(lg);
    
    		Criteria c = new Criteria();
    		c.addCriteria("f_vertrag_status", 1);
    		lg.fetchData(c);
    
    		vlayout.addMember(buttonsLayout);
    
    		addItem(vlayout);
    
    	}
    
    	private void onButtonClick() {
    		Record updateRec = new Record();
    		updateRec.setAttribute("f_id",
    				Integer.parseInt(idItem.getValueAsString()));
    		Integer newStatus = null;
    		if (actualStatus.intValue() == 1) {
    			newStatus = 3;
    		} else {
    			newStatus = 1;
    		}
    		updateRec.setAttribute("f_vertrag_status", newStatus);
    		actualStatus = newStatus;
    		DataSource.get("vertraege").updateData(updateRec, new DSCallback() {
    
    			@Override
    			public void execute(DSResponse dsResponse, Object data,
    					DSRequest dsRequest) {
    				SC.say("OK");
    			}
    		});
    	}
    
    }
    testDatasource.ds.xml
    Code:
    <DataSource ID="testDatasource" serverType="sql" tableName="t_vertrag">
    
    	<fields>
    		<field name="f_id" type="sequence" primaryKey="true" />
    		<field name="f_vertrag_status" type="integer" />
    		
    	</fields>
    
    </DataSource>
    vertraege.ds.xml
    Code:
    <DataSource ID="vertraege" serverType="sql" tableName="t_vertrag" >
    	<fields>
    		<field name="f_id" type="sequence" primaryKey="true" />
    		<field name="f_vertrag_status" type="integer" />
    	</fields>
    
    	<operationBindings>
    		
    		<operationBinding operationType="update">
    			<serverObject className="myCompany.app.server.dmi.StatusDMIHandler"
    				methodName="doUpdate" />
    		</operationBinding>
    
    	</operationBindings>
    
    
    </DataSource>
    The StatusDMIHandler.java
    Code:
    public class StatusDMIHandler {
    
    	public DSResponse doUpdate(DSRequest dsRequest,
    			HttpServletRequest servletRequest) throws Exception {
    
    		DSResponse response = dsRequest.execute();
    
    		RPCManager rpcManager = dsRequest.getRPCManager();
    
    		Integer vertragId = null;
    		Object vertragIdObject = dsRequest.getCriteria().get("f_id");
    		if (vertragIdObject instanceof Long) {
    			vertragId = Integer.valueOf(((Long) vertragIdObject).intValue());
    		} else {
    			vertragId = (Integer) vertragIdObject;
    		}
    
    		DSRequest schuelerRequest = new DSRequest(
    				"testDatasource",
    				DataSource.OP_FETCH, rpcManager);
    		Map<String, Object> criteria = new HashMap<String, Object>();
    		criteria.put("f_id", vertragId);
    		schuelerRequest.setCriteria(criteria);
    		DSResponse schuelerResponse = schuelerRequest.execute();
    		schuelerResponse.setOperationType(DataSource.OP_UPDATE);
    
    		response = response.addRelatedUpdate(schuelerResponse);
    
    		return response;
    
    	}
    }
    The basic idea is that you have a listGrid which shows all ids from the table t_vertrag having criteria: f_vertrag_status = 1.
    Then you can choose one id (writing it on the textField below), and push the button "switch". The f_vertrag_status = 3 is set, and so it should disappear from the listGrid because of the criteria.
    Then, pussing the button "switch" again, f_vertrag_status = 1 is set. This record should appear again at the listGrid.

    So, step by step:
    1) Suppose you have a record with f_id=511 and f_vertrag_status=1, so it is shown in the listGrid.

    Logs until now:
    Code:
    19:00:07.069:INFO:Log:initialized
    19:00:19.653:INFO:Log:isc.Page is loaded
    19:00:21.366:MUP1:INFO:ResultSet:isc_ListGrid_0:Creating new isc.ResultSet for operation 'testDatasource_fetch' with filterValues: {
        "f_vertrag_status":1
    }
    19:00:21.375:MUP1:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):setCriteria: filter criteria changed, invalidating cache
    19:00:21.375:MUP1:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):Invalidating cache
    19:00:21.396:MUP1:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange(0,1), cache check: 0,37 firstMissingRow: 0 lastMissingRow: 37
    19:00:21.396:MUP1:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange: guessing forward scrolling
    19:00:21.396:MUP1:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange(0, 1) will fetch from 0 to 75
    19:00:21.396:MUP1:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):fetching rows 0,75 from server
    19:00:21.864:MUP1:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange(0, 24) satisfied from cache
    19:00:22.012:XRP6:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):Received 75 records from server
    19:00:22.013:XRP6:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):full length set to: 1603
    19:00:22.013:XRP6:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):integrating 75 rows into cache at position 0
    19:00:22.014:XRP6:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):cached 75 rows, from 0 to 75 (1603 total rows, 75 cached)
    19:00:22.040:TMR7:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange(0, 24) satisfied from cache
    2) Write 511 in the textField.
    3) Push "switch".

    The record disappears. This is the expected behavior.
    The logs also show this correctly (updated cache: 0 row(s) added, 0 row(s) updated, 1 row(s) removed.).

    Logs:
    Code:
    19:03:03.484:XRP8:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):dataSource data changed firing
    19:03:03.485:XRP8:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):updating cache in place after operationType: update, cached rows: 75, total rows: 1603
    19:03:03.486:XRP8:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):Updating cache: operationType 'update' (no componentID) ,1 rows update data:
    [
    {f_id: 511,
    f_vertrag_status: 3}
    ]
    19:03:03.490:XRP8:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):row dropped:
    {f_id: 511,
    f_vertrag_status: 3}
    didn't match filter: {
        "f_vertrag_status":1
    }
    19:03:03.490:XRP8:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):updated cache: 0 row(s) added, 0 row(s) updated, 1 row(s) removed.
    19:03:03.569:TMR1:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange(0, 24) satisfied from cache
    DSRequest:
    Code:
    {
        dataSource:"vertraege", 
        operationType:"update", 
        data:{
            f_id:511, 
            f_vertrag_status:3
        }, 
        textMatchStyle:"exact", 
        showPrompt:true, 
        oldValues:{
            f_id:511, 
            f_vertrag_status:3
        }, 
        requestId:"vertraege$6271", 
        fallbackToEval:false, 
        lastClientEventThreadCode:"MUP5", 
        bypassCache:true
    }
    DSResponse:
    Code:
    [
        {
            affectedRows:1, 
            data:[
                {
                    f_id:511, 
                    f_vertrag_status:3
                }
            ], 
            invalidateCache:false, 
            isDSResponse:true, 
            operationType:"update", 
            queueStatus:0, 
            relatedUpdates:[
                {
                    endRow:1, 
                    affectedRows:0, 
                    dataSource:"testDatasource", 
                    totalRows:1, 
                    isDSResponse:true, 
                    invalidateCache:false, 
                    status:0, 
                    operationType:"update", 
                    startRow:0, 
                    data:[
                        {
                            f_id:511, 
                            f_vertrag_status:3
                        }
                    ]
                }
            ], 
            status:0
        }
    ]
    4) Push switch again.
    The record DOES NOT APPEAR again, which I think is not correct. Nevertheless, the logs say that the record should have appeared: (updated cache: 1 row(s) added, 0 row(s) updated, 0 row(s) removed.).

    But I DON'T SEE the record 511 supposely added. Nothing happens with the listGrid. So what is happening here ??

    Code:
    19:06:12.296:XRP5:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):dataSource data changed firing
    19:06:12.297:XRP5:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):updating cache in place after operationType: update, cached rows: 74, total rows: 1602
    19:06:12.299:XRP5:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):Updating cache: operationType 'update' (no componentID) ,1 rows update data:
    [
    {f_id: 511,
    f_vertrag_status: 1}
    ]
    19:06:12.303:XRP5:WARN:Log:findByKeys: passed record does not have a value for key field 'f_id'
    19:06:12.305:XRP5:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):updated row returned by server doesn't match any cached row,  adding as new row.  Primary key values: {f_id: 511}, complete row: {f_id: 511,
    f_vertrag_status: 1}
    19:06:12.305:XRP5:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):updated cache: 1 row(s) added, 0 row(s) updated, 0 row(s) removed.
    19:06:12.394:TMR9:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange(0, 24) satisfied from cache
    DSRequest.
    Code:
    {
        dataSource:"vertraege", 
        operationType:"update", 
        data:{
            f_id:511, 
            f_vertrag_status:1
        }, 
        textMatchStyle:"exact", 
        showPrompt:true, 
        oldValues:{
            f_id:511, 
            f_vertrag_status:1
        }, 
        requestId:"vertraege$6272", 
        fallbackToEval:false, 
        lastClientEventThreadCode:"MUP2", 
        bypassCache:true
    }
    DSResponse:
    Code:
    [
        {
            affectedRows:1, 
            data:[
                {
                    f_id:511, 
                    f_vertrag_status:1
                }
            ], 
            invalidateCache:false, 
            isDSResponse:true, 
            operationType:"update", 
            queueStatus:0, 
            relatedUpdates:[
                {
                    endRow:1, 
                    affectedRows:0, 
                    dataSource:"testDatasource", 
                    totalRows:1, 
                    isDSResponse:true, 
                    invalidateCache:false, 
                    status:0, 
                    operationType:"update", 
                    startRow:0, 
                    data:[
                        {
                            f_id:511, 
                            f_vertrag_status:1
                        }
                    ]
                }
            ], 
            status:0
        }
    ]
    Using SmartGWT v9.1p_2014-09-25/PowerEdition Deployment with MSSQL 2014.

    Comment


      #3
      You've got the same data being returned as the normal update data *and* as a relatedUpdate. This is not necessarily invalid but it's definitely redundant. Does the problem go away for you if you stop doing this?

      Comment


        #4
        I don't quite understand what you mean.

        In the testcase I have two datasources which are basically equal, yes. In my original application this is different: I have two very different datasources, but the problem is the same: that the listgrid's datasource doesn't update correctly when updating the other datasource. So, in my application, the data returned as the normal update data and the related update are very different.
        In my testcase they are the same only in order to keep it simple .. but the issue is the same.

        Comment


          #5
          As Blama described in http://forums.smartclient.com/showthread.php?t=31347 , this is exactly what I am doing here:
          my view datasource is "testDatasource", while my update datasource is "vertraege". In this special test case, both are equal. But in my real application, they are very different. But still, the issue is the same. Are you able to reproduce the problem?

          Comment


            #6
            Hi edulid,

            I'd expect this to work, too.
            If there is really a bug, it should be on the client, because the DSRequests/DSResponse pairs seem to look good.

            What happens if you do not use the criteria?
            Does the changed record show up then?

            Best regards,
            Blama

            Comment


              #7
              I changed the "update" to an "add" dsRequest, and removed the criteria, and the same:
              I see in the logs:
              11:36:49.678:XRP4:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):updated cache: 1 row(s) added, 0 row(s) updated, 0 row(s) removed.

              But I don't see any new row in the listGrid.

              Comment


                #8
                Originally posted by edulid View Post
                In the testcase I have two datasources which are basically equal, yes. In my original application this is different: I have two very different datasources, but the problem is the same: that the listgrid's datasource doesn't update correctly when updating the other datasource. So, in my application, the data returned as the normal update data and the related update are very different.
                In my testcase they are the same only in order to keep it simple .. but the issue is the same.
                Actually the symptom is the same but the cause could be totally different. Again please try getting rid of the redundant update.

                Also, can you clarify how you're determining that the new record is "not in the grid". It looks like you have partially loaded data; are you aware of where you should expect to see newly added rows in this case?

                Comment


                  #9
                  New test case:

                  (All other files are equal).

                  MyWindow3.java:
                  Code:
                  public class MyWindow3 extends Window {
                  
                  	private final ListGrid lg;
                  
                  	private final IButton button;
                  
                  	private Integer actualStatus = 1;
                  
                  	TextItem idItem;
                  	
                  	public MyWindow3() {
                  		setWidth(700);
                  		setHeight(500);
                  		setAutoCenter(true);
                  		setIsModal(true);
                  		setShowModalMask(true);
                  		setShowMaximizeButton(true);
                  
                  		VLayout vlayout = new VLayout(12);
                  		vlayout.setPadding(25);
                  
                  		lg = new ListGrid();
                  		lg.setDataSource(DataSource.get("testDatasource"));
                  
                  		lg.setWidth100();
                  		lg.setHeight100();
                  		lg.setSortField("f_id");
                  
                  		lg.setAutoFetchData(false);
                  
                  		HLayout buttonsLayout = new HLayout(15);
                  		buttonsLayout.setHeight(25);
                  		buttonsLayout.setAlign(Alignment.LEFT);
                  
                  		DynamicForm df = new DynamicForm();
                  		idItem = new TextItem("id");
                  		df.setFields(idItem);
                  
                  		buttonsLayout.addMember(df);
                  
                  		button = new IButton("Switch status");
                  		button.setWidth(200);
                  		button.addClickHandler(new ClickHandler() {
                  			@Override
                  			public void onClick(ClickEvent event) {
                  				onButtonClick();
                  			}
                  		});
                  
                  		buttonsLayout.addMember(button);
                  
                  		vlayout.addMember(lg);
                  
                  		Criteria c = new Criteria();
                  		c.addCriteria("f_vertrag_status", 1);
                  		lg.fetchData(c);
                  		
                  		vlayout.addMember(buttonsLayout);
                  
                  		addItem(vlayout);
                  
                  	}
                  
                  	private void onButtonClick() {
                  		Record updateRec = new Record();
                  		updateRec.setAttribute("f_id",
                  				Integer.parseInt(idItem.getValueAsString()));
                  		Integer newStatus = null;
                  		if (actualStatus.intValue() == 1) {
                  			newStatus = 3;
                  		} else {
                  			newStatus = 1;
                  		}
                  		updateRec.setAttribute("f_vertrag_status", newStatus);
                  		actualStatus = newStatus;
                  		DataSource.get("vertraege").updateData(updateRec, new DSCallback() {
                  
                  			@Override
                  			public void execute(DSResponse dsResponse, Object data,
                  					DSRequest dsRequest) {
                  				//SC.say("OK");
                  			}
                  		});
                  	}
                  
                  }
                  testDatasource.ds.xml
                  Code:
                  <DataSource ID="testDatasource" serverType="sql" tableName="t_vertrag">
                  
                  	<fields>
                  		<field name="f_id" type="sequence" primaryKey="true" />
                  		<field name="f_vertrag_status" type="integer" />
                  		<field name="f_name" type="text" customSelectExpression="left(s.f_name,1) + '_' + left(s.f_vorname,1) " />
                  		
                  	</fields>
                  	
                  	<operationBindings>
                   		<operationBinding operationType="fetch" >
                   			<tableClause>
                   				t_vertrag left join t_schueler as s 
                   				on s.f_schueler_id = t_vertrag.f_schueler_id
                   			</tableClause>
                  		</operationBinding>
                   	</operationBindings>
                  
                  </DataSource>
                  As I mentioned, testDatasource is my "view". So here I have a field "f_name", which consists just of the first letters of the fields f_name and f_vorname. The table t_vertrag has a field f_schueler_id , which, as you see in the DS, is the foreign key (points to t_schueler.f_schueler_id).

                  This datasource is different than the "vertraege" datasource, which is used only for updating the values.

                  Open window:

                  1) Fetch initial values

                  Code:
                  09:14:54.860:INFO:Log:initialized
                  09:14:55.665:INFO:Log:isc.Page is loaded
                  09:15:05.283:MUP1:INFO:ResultSet:isc_ListGrid_0:Creating new isc.ResultSet for operation 'testDatasource_fetch' with filterValues: {
                      "f_vertrag_status":1
                  }
                  09:15:05.287:MUP1:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):setCriteria: filter criteria changed, invalidating cache
                  09:15:05.288:MUP1:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):Invalidating cache
                  09:15:05.293:MUP1:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange(0,1), cache check: 0,37 firstMissingRow: 0 lastMissingRow: 37
                  09:15:05.293:MUP1:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange: guessing forward scrolling
                  09:15:05.293:MUP1:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange(0, 1) will fetch from 0 to 75
                  09:15:05.293:MUP1:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):fetching rows 0,75 from server
                  09:15:05.570:MUP1:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange(0, 22) satisfied from cache
                  09:15:05.765:XRP3:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):Received 75 records from server
                  09:15:05.766:XRP3:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):full length set to: 1615
                  09:15:05.766:XRP3:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):integrating 75 rows into cache at position 0
                  09:15:05.768:XRP3:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):cached 75 rows, from 0 to 75 (1615 total rows, 75 cached)
                  09:15:05.778:TMR4:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange(0, 22) satisfied from cache
                  DSRequest
                  Code:
                  {
                      dataSource:"testDatasource", 
                      operationType:"fetch", 
                      componentId:"isc_ListGrid_0", 
                      data:{
                          f_vertrag_status:1
                      }, 
                      startRow:0, 
                      endRow:75, 
                      sortBy:[
                          "f_id"
                      ], 
                      textMatchStyle:"exact", 
                      resultSet:[ResultSet ID:isc_ResultSet_0 (created by: isc_ListGrid_0)], 
                      callback:{
                          caller:[ResultSet ID:isc_ResultSet_0 (created by: isc_ListGrid_0)], 
                          methodName:"fetchRemoteDataReply"
                      }, 
                      willHandleError:true, 
                      showPrompt:true, 
                      prompt:"Suche Datensätze die den Kriterien entsprechen...", 
                      oldValues:{
                          f_vertrag_status:1
                      }, 
                      requestId:"testDatasource$6270", 
                      internalClientContext:{
                          requestIndex:1
                      }, 
                      fallbackToEval:false, 
                      lastClientEventThreadCode:"MUP1", 
                      bypassCache:true
                  }
                  Code:
                  DSResponse:
                  [
                      {
                          affectedRows:0, 
                          data:[
                              {
                                  f_name:"R_L", 
                                  rowID:1, 
                                  f_id:57, 
                                  f_vertrag_status:1
                              }, 
                              {
                                  f_name:"P_A", 
                                  rowID:2, 
                                  f_id:112, 
                                  f_vertrag_status:1
                              }, 
                              {
                                  f_name:"J_J", 
                                  rowID:3, 
                                  f_id:159, 
                                  f_vertrag_status:1
                              }, 
                  
                  .....
                  Initial screenshot:
                  1.png

                  2) Write 811 on "id"
                  3) Push "switch"

                  Code:
                  09:19:03.571:XRP5:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):dataSource data changed firing
                  09:19:03.571:XRP5:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):updating cache in place after operationType: update, cached rows: 75, total rows: 1615
                  09:19:03.571:XRP5:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):Updating cache: operationType 'update' (no componentID) ,1 rows update data:
                  [
                  {f_name: "K_N",
                  f_id: 804,
                  f_vertrag_status: 3}
                  ]
                  09:19:03.574:XRP5:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):row dropped:
                  {f_name: "K_N",
                  f_id: 804,
                  f_vertrag_status: 3}
                  didn't match filter: {
                      "f_vertrag_status":1
                  }
                  09:19:03.574:XRP5:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):updated cache: 0 row(s) added, 0 row(s) updated, 1 row(s) removed.
                  09:19:03.603:TMR6:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange(0, 22) satisfied from cache
                  DSRequest:
                  Code:
                  {
                      dataSource:"vertraege", 
                      operationType:"update", 
                      data:{
                          f_id:804, 
                          f_vertrag_status:3
                      }, 
                      textMatchStyle:"exact", 
                      showPrompt:true, 
                      oldValues:{
                          f_id:804, 
                          f_vertrag_status:3
                      }, 
                      requestId:"vertraege$6271", 
                      fallbackToEval:false, 
                      lastClientEventThreadCode:"MUP2", 
                      bypassCache:true
                  }
                  DSResponse:
                  Code:
                  [
                      {
                          affectedRows:1, 
                          data:[
                              {
                                  f_id:804, 
                                  f_vertrag_status:3
                              }
                          ], 
                          invalidateCache:false, 
                          isDSResponse:true, 
                          operationType:"update", 
                          queueStatus:0, 
                          relatedUpdates:[
                              {
                                  endRow:1, 
                                  affectedRows:0, 
                                  dataSource:"testDatasource", 
                                  totalRows:1, 
                                  isDSResponse:true, 
                                  invalidateCache:false, 
                                  status:0, 
                                  operationType:"update", 
                                  startRow:0, 
                                  data:[
                                      {
                                          f_name:"K_N", 
                                          f_id:804, 
                                          f_vertrag_status:3
                                      }
                                  ]
                              }
                          ], 
                          status:0
                      }
                  ]
                  Screenshot:
                  2.png

                  As you see in the logs and in the screenshot, the record with Id= 804 dissapears from the grid, which is the correct behavior.

                  4) push "switch" again

                  Code:
                  09:22:04.112:XRP5:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):dataSource data changed firing
                  09:22:04.113:XRP5:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):updating cache in place after operationType: update, cached rows: 74, total rows: 1614
                  09:22:04.113:XRP5:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):Updating cache: operationType 'update' (no componentID) ,1 rows update data:
                  [
                  {f_name: "K_N",
                  f_id: 804,
                  f_vertrag_status: 1}
                  ]
                  09:22:04.117:XRP5:WARN:Log:findByKeys: passed record does not have a value for key field 'f_id'
                  09:22:04.117:XRP5:INFO:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):updated row returned by server doesn't match any cached row,  adding as new row.  Primary key values: {f_id: 804}, complete row: {f_name: "K_N",
                  f_id: 804,
                  f_vertrag_status: 1}
                  09:22:04.117:XRP5:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):updated cache: 1 row(s) added, 0 row(s) updated, 0 row(s) removed.
                  09:22:04.138:TMR6:DEBUG:ResultSet:isc_ResultSet_0 (created by: isc_ListGrid_0):getRange(0, 22) satisfied from cache
                  DSRequest
                  Code:
                  {
                      dataSource:"vertraege", 
                      operationType:"update", 
                      data:{
                          f_id:804, 
                          f_vertrag_status:1
                      }, 
                      textMatchStyle:"exact", 
                      showPrompt:true, 
                      oldValues:{
                          f_id:804, 
                          f_vertrag_status:1
                      }, 
                      requestId:"vertraege$6272", 
                      fallbackToEval:false, 
                      lastClientEventThreadCode:"MUP2", 
                      bypassCache:true
                  }
                  DSResponse
                  Code:
                  [
                      {
                          affectedRows:1, 
                          data:[
                              {
                                  f_id:804, 
                                  f_vertrag_status:1
                              }
                          ], 
                          invalidateCache:false, 
                          isDSResponse:true, 
                          operationType:"update", 
                          queueStatus:0, 
                          relatedUpdates:[
                              {
                                  endRow:1, 
                                  affectedRows:0, 
                                  dataSource:"testDatasource", 
                                  totalRows:1, 
                                  isDSResponse:true, 
                                  invalidateCache:false, 
                                  status:0, 
                                  operationType:"update", 
                                  startRow:0, 
                                  data:[
                                      {
                                          f_name:"K_N", 
                                          f_id:804, 
                                          f_vertrag_status:1
                                      }
                                  ]
                              }
                          ], 
                          status:0
                      }
                  ]
                  Screenshot: 3.png

                  As you see in the logs, the record should be added to the grid. But as you see in 3.png, the listgrid did not change since 2.png, ... the supposely added record is nowhere.
                  If I have an "add" operation, and the relatedUpdate() method also simulates an "add" operation, the record is inserted correctly to the beginning of the listGrid, so this is different from this thread's testcase behavior, where the record is not added to the list at all (3.png).

                  The two data sources are now different and they return different data, and the behavior is the same.
                  Attached Files
                  Last edited by edulid; 29 Sep 2014, 23:43.

                  Comment


                    #10
                    Sorry you're spending so much time on test cases, but this modified test case has exactly the same problem as before: you have a response to an "update" showing the new record as expected, then you add a relatedUpdate that *provides further modifications to the same record*.

                    This isn't what relatedUpdates are for. Related updates are for telling the client about updates to *other, related records* (hence the word "related").

                    As a very quick check, just remove the server code that tries to add related updates at all. If that doesn't fix the behavior, then you seem to be reporting that cache updates in general don't work, which doesn't make a lot of sense.

                    Comment


                      #11
                      Hi,

                      this listGrid is very important to me, since all my application is based on this listgrid and that it shows actual, up-to-date information, that's why I'm spending this time trying to understand what's happening here.

                      Thank you for your help.

                      Are you sure that the relatedUpdated "provides further modifications of the same record", as you claim?
                      My relatedUpdate is a simple fetch, which only SIMULATES an update, in order to update the listgrid's showing "testDatasource" data. Please take a look at my comments:

                      Code:
                      // First I will FETCH the "testDatasource", in order to get the rest of the fields that I don't know at this moment. 
                      DSRequest schuelerRequest = new DSRequest(
                      				"testDatasource",
                      				DataSource.OP_FETCH, rpcManager);
                      		Map<String, Object> criteria = new HashMap<String, Object>();
                      		criteria.put("f_id", vertragId);
                      		schuelerRequest.setCriteria(criteria);
                      // I will execute the FETCH now:
                      		DSResponse schuelerResponse = schuelerRequest.execute();
                      // now I simulate an update ON THE RESPONSE. So I set the operationType=update. But no update is executed now!	
                      schuelerResponse.setOperationType(DataSource.OP_UPDATE);
                      // we want to inform the client
                      response = response.addRelatedUpdate(schuelerResponse);
                      So I am telling the client components, that *other, related records* have to be updated (the actual record is the updated "vertraege" record, so "other, related records" refers to the fetched- "testDatasource" record.

                      then you seem to be reporting that cache updates in general don't work, which doesn't make a lot of sense.
                      Please take a deeper look: in the past, you have told me similar things:
                      Originally posted by Isomorphic View Post
                      There is no plausible mechanism by which framework code could be storing this value permanently at the JVM level (we do not put anything in the HttpSession at all) so you should investigate any custom logic you have added server-side - this is not a framework issue.
                      or
                      Originally posted by Isomorphic View Post
                      We weren't able to reproduce the issue with your test case, and again you seem to be claiming some kind of server-side persistence, which doesn't make sense.
                      Refer to http://forums.smartclient.com/showthread.php?t=31159

                      After investigating deeper, you found out that this was indeed a bug related specifically to MSSQL Server.
                      Last edited by edulid; 30 Sep 2014, 14:11.

                      Comment


                        #12
                        Originally posted by Isomorphic View Post

                        As a very quick check, just remove the server code that tries to add related updates at all.
                        If I remove the
                        response.addRelatedUpdate(schuelerResponse);
                        , the listGrid doesn't get updated, of course, because it cannot possibly know that a change to the datasource "vertraege" was made. The update was made to the "vertraege" datasource, and the listGrid displays the "testDatasource" datasource.

                        !!! Please note that we are using two different datasources here:
                        1) testDatasource: used by the listGrid. It provides a "view" on the data.
                        2) vertraege: it may be updated, as in the test case.

                        Have you been able to execute my test case? What behavior are you seeing ?
                        Last edited by edulid; 30 Sep 2014, 14:15.

                        Comment


                          #13
                          There's no way this could be related to SQL Server since you've already shared the response data and it's correct. The client-side system just sees the DSResponse and doesn't even have a way to find out what database is in use on the server side (Blama actually pointed this out too).

                          You're correct, the new code you posted does use two different DataSources, sorry, we didn't immediately see the specific way that the new code was intended to be combined with the old.

                          Note that the code you've shared falls short of the requirements for a test case - it relies on SQL schema we don't have, it has what looks like probably DB-specific SQL, and to replicate the situation exactly we'd need thousands of rows of sample data. Nevertheless since you've made so many attempts at this, we'll correct all these problems with the test code and see if we can replicate the problem.

                          Comment


                            #14
                            Originally posted by edulid View Post


                            The StatusDMIHandler.java
                            Code:
                            public class StatusDMIHandler {
                            
                            	public DSResponse doUpdate(DSRequest dsRequest,
                            			HttpServletRequest servletRequest) throws Exception {
                            
                            		DSResponse response = dsRequest.execute();
                            
                            		RPCManager rpcManager = dsRequest.getRPCManager();
                            
                            		Integer vertragId = null;
                            		Object vertragIdObject = dsRequest.getCriteria().get("f_id");
                            		if (vertragIdObject instanceof Long) {
                            			vertragId = Integer.valueOf(((Long) vertragIdObject).intValue());
                            		} else {
                            			vertragId = (Integer) vertragIdObject;
                            		}
                            
                            		DSRequest schuelerRequest = new DSRequest(
                            				"testDatasource",
                            				DataSource.OP_FETCH, rpcManager);
                            		Map<String, Object> criteria = new HashMap<String, Object>();
                            		criteria.put("f_id", vertragId);
                            		schuelerRequest.setCriteria(criteria);
                            		DSResponse schuelerResponse = schuelerRequest.execute();
                            		schuelerResponse.setOperationType(DataSource.OP_UPDATE);
                            
                            		response = response.addRelatedUpdate(schuelerResponse);
                            
                            		return response;
                            
                            	}
                            }
                            Actually it's the same DMI code I posted at the beginning of this thread (http://forums.smartclient.com/showpo...18&postcount=2) :-) That's why I was so confused with your answers.

                            If you take a look at my FIRST code (the one here: http://forums.smartclient.com/showpo...18&postcount=2 ) , it's simpler than the second code, and it still uses two datasources: "testdatasource" and "vertraege".. these are almost equal, but still are two different datasources.

                            There are no "DB-specific SQL" there, again, at my FIRST code, and the ONLY table is:
                            Code:
                            <fields>
                            		<field name="f_id" type="sequence" primaryKey="true" />
                            		<field name="f_vertrag_status" type="integer" />
                            	</fields>
                            The table schema is very simple:
                            Code:
                            CREATE TABLE t_vertrag(
                            	f_id int IDENTITY(1,1) NOT NULL,
                            	f_vertrag_status int NULL);
                            which as you see, has nothing special.
                            The records in the table are also nothing special, just add random values, but please more than 75 values. f_vertrag_status should have either value=1 or 3, because the test code switches between these two values.

                            So, I would suggest that you use the FIRST test case, as it is simpler and it shows the same behavior. Again, the code is here: http://forums.smartclient.com/showpo...18&postcount=2

                            Thank you.
                            Last edited by edulid; 30 Sep 2014, 15:40.

                            Comment


                              #15
                              Ah, we see, it looks like you tried to modify the test case so there was actually a DB-level relation. That would not have affected behavior, so yes, we'll use the first test case as a starting point.

                              However, we just realized you never answered this:

                              Also, can you clarify how you're determining that the new record is "not in the grid". It looks like you have partially loaded data; are you aware of where you should expect to see newly added rows in this case?
                              The docs in question are:

                              If updatePartialCache is enabled and an "add" or "update" operation succeeds with a partial cache:

                              o updated rows will remain in their current position. No attempt will be made to sort them into a new position even if the sort field was updated.

                              o newly added rows will be added at either the end (first preference) or beginning of the dataset if that part of the dataset is cached and was most recently requested. If not, the new row is added at the end of the most recently requested contiguously cached range.

                              The cache will then be dropped the next time rows are fetched, to prevent problems with inconsistent row numbering between the server and client, which could otherwise lead to duplicate rows or rows being skipped entirely.
                              So a couple of things here:

                              1. have you checked whether the newly added row is now in the cache, but not visible in the grid viewport? You can just search the dataset via ResultSet.find()

                              2. the behavior you're hoping for is actually not specified (the docs don't cover what's supposed to happen when an "update" results in a newly added row), and it's not clear, from a design perspective, whether it's actually desirable for a *related update* which did not involve any end user input, to suddenly pop into view. The behaviors we specify for updatePartialCache are designed to help users maintain context when they have actually just changed or added a record. When the server tells us about a "relatedUpdate" it's not clear that this is immediately relevant to the user and should be prominently placed into view.

                              So:

                              1. we're going to check on behavior with the test case anyway, since we see at least one log statement that doesn't make sense, but please answer #1 regardless

                              2. we're leaning toward the conclusion that what you expect to happen should not actually be the default behavior of the framework. Instead, what you might want to do in this use case is to grab the data in the existing ResultSet and create a new ResultSet from it, placing the new row in whatever visual position you prefer.

                              Comment

                              Working...
                              X