Announcement

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

    ListGrid sort by multiple fields

    Hi,

    I use a ListGrid in combination with a SQL DataSource. I want to use a sort by two fields, but the result is only sorted by the first of the two fields.

    In the server log file I got the following message:

    WARN DSRequest - getSortBy() called on dsRequest containing multiple sortBy fields, returning first in list.



    Is there a problem with multiple sort fields and SQL DataSources?

    Chris

    #2
    That warning is spurious and no longer occurs in the latest builds. There is no known issue with SQL and multi-field sort, as you can see it's working in samples. Just make sure all fields you're trying to sort by are declared, and post the DataSource, ListGrid configuration, RPC tab contents and server-side log for the request if having trouble (always do this).

    Comment


      #3
      I moved on to the latest nightly (2011.02.14), but sadly the problem is still occurring.

      In the DSRequest you see the sort order fields emi_first_name and emi_last_name. In the SQL statement (Server-Log) olny the field emi_last_name is used in the order clause and the sort order in the response is consequently wrong.

      ListGrid:
      Code:
      employeeSelectionGrid.setCanEdit(false);
      		employeeSelectionGrid.setShowAllRecords(false);
      		employeeSelectionGrid.setCellHeight(22);
      		employeeSelectionGrid.setDataSource(amEmployeeCurrentSearchDS);
      		employeeSelectionGrid.setAutoFetchData(false);
      		employeeSelectionGrid.setCanMultiSort(true);
      		employeeSelectionGrid.setShowFilterEditor(false);
      		employeeSelectionGrid.setSelectionType(SelectionStyle.SINGLE);
      		SortSpecifier[] initialSort = new SortSpecifier[2];
      		initialSort[0] = new SortSpecifier(
      				GeneratedFieldConsts.F_EMI_LAST_NAME, SortDirection.ASCENDING);
      		initialSort[1] = new SortSpecifier(
      				GeneratedFieldConsts.F_EMI_FIRST_NAME, SortDirection.ASCENDING);
      		employeeSelectionGrid.setInitialSort(initialSort);
      		employeeSelectionGrid.setFilterOnKeypress(true);
      		employeeSelectionGrid.setHeight100();
      DataSource:
      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <DataSource ID="am_employee_current_search" serverType="sql"
      	tableName="sdm$vi_web_employee_current" qulifyColumnNames="false" >
      	<fields>
      		<field name="emi_last_name" title="Nachname" type="text" />
      		<field name="emi_first_name" title="Vorname" type="text" />
      		<field name="emi_costplace" title="Kostenstelle" type="text" />
      		<field name="emi_staff_identification" title="Personalnummer"
      			type="text" />
      		<field name="emi_organisation_unit" title="Orgeinheit (SAP)"
      			type="text" />
      		<field name="uni_1_id" type="integer" detail="true" />
      		<field name="uni_2_id" type="integer" detail="true" />
      		<field name="uni_3_id" type="integer" detail="true" />
      		<field name="uni_4_id" type="integer" detail="true" />
      		<field name="uni_5_id" type="integer" detail="true" />
      		<field name="uni_1_name" title="Team" type="text" />
      		<field name="uni_2_name" title="Abteilung" type="text" detail="true" />
      		<field name="uni_3_name" title="CCM" type="text" detail="true" />
      		<field name="uni_4_name" title="Bereich" type="text" detail="true" />
      		<field name="uni_5_name" title="Mandant" type="text" detail="true" />
      		<field name="emp_id" type="integer" primaryKey="true" detail="true" />
      		<field name="emp_is_locked" type="integer" detail="true" />		
      	</fields>
      	<serverObject lookupStyle="new"
      		className="de.tmobile.sdom.frontend.server.dmi.AMEmployeeCurrentSearchDMI" />
      	<operationBindings>
      		<operationBinding operationType="fetch"
      			customValueFields="emi_last_name,emi_first_name" customCriteriaFields="emi_last_name,emi_first_name">			
      			<selectClause>distinct sdm$vi_web_employee_current.uni_3_id, 
      						sdm$vi_web_employee_current.uni_2_name,
      						sdm$vi_web_employee_current.emi_organisation_unit, 
      						sdm$vi_web_employee_current.uni_1_name,sdm$vi_web_employee_current.emi_staff_identification, 
      						sdm$vi_web_employee_current.uni_4_id,sdm$vi_web_employee_current.emp_id, 
      						sdm$vi_web_employee_current.emi_first_name,sdm$vi_web_employee_current.uni_5_name, 
      						sdm$vi_web_employee_current.uni_2_id,sdm$vi_web_employee_current.uni_5_id, 
      						sdm$vi_web_employee_current.emi_costplace,sdm$vi_web_employee_current.uni_4_name, 
      						sdm$vi_web_employee_current.uni_1_id,sdm$vi_web_employee_current.uni_3_name, 
      						sdm$vi_web_employee_current.emp_is_locked,sdm$vi_web_employee_current.emi_last_name</selectClause>
      			<tableClause>sdm$vi_web_employee_current
      				left join sdm$vi_web_unit_attribute on uat_emp_id = emp_id and
      				trunc(sysdate) between uat_valid_from and uat_valid_to</tableClause>
      			<whereClause>
      			<![CDATA[(1=$switch or uat_att_id = $att_id)]]>
      				and ($defaultWhereClause)
      			</whereClause>
      		</operationBinding>
      	</operationBindings>
      DMI:
      Code:
      	public DSResponse fetch(DSRequest dsRequest) throws Exception {
      
      		DSResponse dsResponse = null;
      
      		Integer pSwitch = ConvServer.toInt(dsRequest.getHttpServletRequest()
      				.getParameter("switch"));
      		Integer pAttId = ConvServer.toInt(dsRequest.getHttpServletRequest()
      				.getParameter(Consts.F_ATT_ID));
      		dsRequest.addToTemplateContext("switch", pSwitch);
      		dsRequest.addToTemplateContext(Consts.F_ATT_ID, pAttId);
      		dsResponse = dsRequest.execute();
      		
      		return dsResponse;
      	}
      }
      DSRequest:

      Code:
      {
          "dataSource":"am_employee_current_search", 
          "operationType":"fetch", 
          "componentId":"isc_AgentManagerTab_2_0", 
          "data":{
              "operator":"and", 
              "criteria":[
                  {
                      "fieldName":"emi_last_name", 
                      "operator":"iStartsWith", 
                      "value":"Müller"
                  }, 
                  {
                      "operator":"or", 
                      "criteria":[
                          {
                              "fieldName":"uni_1_name", 
                              "operator":"isNull"
                          }, 
                          {
                              "fieldName":"uni_1_name", 
                              "operator":"notStartsWith", 
                              "value":"Ausg"
                          }
                      ]
                  }
              ]
          }, 
          "startRow":0, 
          "endRow":75, 
          "sortBy":[
              "emi_last_name", 
              "emi_first_name"
          ], 
          "textMatchStyle":"exact", 
          "resultSet":[ResultSet ID:isc_ResultSet_2 (created by: isc_AgentManagerTab_2_0)], 
          "callback":{
              "caller":[ResultSet ID:isc_ResultSet_2 (created by: isc_AgentManagerTab_2_0)], 
              "methodName":"fetchRemoteDataReply"
          }, 
          "willHandleError":true, 
          "showPrompt":true, 
          "prompt":"Suche Datensätze die den Kriterien entsprechen...", 
          "oldValues":{
              "operator":"and", 
              "criteria":[
                  {
                      "fieldName":"emi_last_name", 
                      "operator":"iStartsWith", 
                      "value":"Müller"
                  }, 
                  {
                      "operator":"or", 
                      "criteria":[
                          {
                              "fieldName":"uni_1_name", 
                              "operator":"isNull"
                          }, 
                          {
                              "fieldName":"uni_1_name", 
                              "operator":"notStartsWith", 
                              "value":"Ausg"
                          }
                      ]
                  }
              ]
          }, 
          "clientContext":{
              "requestIndex":1
          }, 
          "requestId":"am_employee_current_search$62714"
      }
      DSResponse:
      Code:
      [
          {
              endRow:75, 
              queueStatus:0, 
              totalRows:221, 
              isDSResponse:true, 
              invalidateCache:false, 
              status:0, 
              startRow:0, 
              data:[
                  {
                      emi_first_name:"W…", 
                      emi_last_name:"Müller"
      …
                  }, 
                  {
                      emi_first_name:"U..", 
                      emi_last_name:"Müller"
      …
                  }, 
                  {
                      emi_first_name:"M..", 
                      emi_last_name:"Müller"
      …
                  },
      …
      ]
      Server-Log:

      Code:
      == 2011-02-15 10:47:34,324 [0-21] INFO  RequestContext - URL: '/frontend/sc/system/development/ISC_ServerLogViewer.js', User-Agent: 'Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.0.2) Gecko/2008091620 Firefox/3.0.2 (.NET CLR 3.5.30729)': Moz (Gecko) with Accept-Encoding header
      === 2011-02-15 10:47:34,340 [0-21] INFO  Download - done streaming: C:/DEV/svn/SDOM/trunk/java/frontend/war/frontend/sc/system/development/ISC_ServerLogViewer.js
      === 2011-02-15 10:47:56,961 [0-12] DEBUG RequestContext - Setting headers to disable caching
      === 2011-02-15 10:47:56,961 [0-12] DEBUG RPCManager - Content type for RPC transaction: text/plain; charset=UTF-8
      === 2011-02-15 10:47:56,961 [0-12] DEBUG RequestContext - Getting output stream via servletResponse.getWriter()
      === 2011-02-15 10:47:56,961 [0-12] DEBUG DataSource - In DS.forName() for 'am_employee_current_search' with DSRequest: com.isomorphic.datasource.DSRequest@136e788
      === 2011-02-15 10:47:56,961 [0-12] DEBUG DataSource - Creating instance of DataSource 'am_employee_current_search'
      === 2011-02-15 10:47:56,961 [0-12] DEBUG RPCManager - DMI response, dropExtraFields: true
      === 2011-02-15 10:47:56,961 [0-12] DEBUG DataSource - In DS.forName() for 'am_employee_current_search' with DSRequest: com.isomorphic.datasource.DSRequest@136e788
      === 2011-02-15 10:47:56,961 [0-12] DEBUG DataSource - Creating instance of DataSource 'am_employee_current_search'
      === 2011-02-15 10:47:56,992 [0-12] DEBUG DataSource - In DS.forName() for 'integer' with DSRequest: com.isomorphic.datasource.DSRequest@136e788
      === 2011-02-15 10:47:56,992 [0-12] DEBUG DataSource - In DS.forName() for 'text' with DSRequest: com.isomorphic.datasource.DSRequest@136e788
      === 2011-02-15 10:47:56,992 [0-12] DEBUG SQLTransaction - Ending Oracle transaction "9758530"
      === 2011-02-15 10:48:00,992 [0-19] DEBUG AppBase - [builtinApplication.am_employee_current_search_fetch] No userTypes defined, allowing anyone access to all operations for this application
      === 2011-02-15 10:48:00,992 [0-19] DEBUG AppBase - [builtinApplication.am_employee_current_search_fetch] No public zero-argument method named '_am_employee_current_search_fetch' found, performing generic datasource operation
      === 2011-02-15 10:48:00,992 [0-19] INFO  SQLDataSource - [builtinApplication.am_employee_current_search_fetch] Performing fetch operation with
      	criteria: {operator:"and",criteria:[{fieldName:"emi_last_name",operator:"iStartsWith",value:"Müller"},{operator:"or",criteria:[{fieldName:"uni_1_name",operator:"isNull"},{fieldName:"uni_1_name",operator:"notStartsWith",value:"Ausg"}]}],_constructor:"AdvancedCriteria"}	values: {operator:"and",criteria:[{fieldName:"emi_last_name",operator:"iStartsWith",value:"Müller"},{operator:"or",criteria:[{fieldName:"uni_1_name",operator:"isNull"},{fieldName:"uni_1_name",operator:"notStartsWith",value:"Ausg"}]}],_constructor:"AdvancedCriteria"}
      === 2011-02-15 10:48:01,023 [0-19] INFO  SQLDataSource - [builtinApplication.am_employee_current_search_fetch] derived query: SELECT distinct sdm$vi_web_employee_current.uni_3_id, 
      						sdm$vi_web_employee_current.uni_2_name,
      						sdm$vi_web_employee_current.emi_organisation_unit, 
      						sdm$vi_web_employee_current.uni_1_name,sdm$vi_web_employee_current.emi_staff_identification, 
      						sdm$vi_web_employee_current.uni_4_id,sdm$vi_web_employee_current.emp_id, 
      						sdm$vi_web_employee_current.emi_first_name,sdm$vi_web_employee_current.uni_5_name, 
      						sdm$vi_web_employee_current.uni_2_id,sdm$vi_web_employee_current.uni_5_id, 
      						sdm$vi_web_employee_current.emi_costplace,sdm$vi_web_employee_current.uni_4_name, 
      						sdm$vi_web_employee_current.uni_1_id,sdm$vi_web_employee_current.uni_3_name, 
      						sdm$vi_web_employee_current.emp_is_locked,sdm$vi_web_employee_current.emi_last_name FROM sdm$vi_web_employee_current
      				left join sdm$vi_web_unit_attribute on uat_emp_id = emp_id and
      				trunc(sysdate) between uat_valid_from and uat_valid_to WHERE 
      			(1=$switch or uat_att_id = $att_id)
      				and ($defaultWhereClause)
      			 ORDER BY $defaultOrderClause
      === 2011-02-15 10:48:01,023 [0-19] DEBUG SQLDataSource - [builtinApplication.am_employee_current_search_fetch] Executing row count query: SELECT COUNT(*) FROM sdm$vi_web_employee_current
      				left join sdm$vi_web_unit_attribute on uat_emp_id = emp_id and
      				trunc(sysdate) between uat_valid_from and uat_valid_to WHERE 
      			(1=$switch or uat_att_id = $att_id)
      				and ($defaultWhereClause)
      			
      === 2011-02-15 10:48:01,023 [0-19] DEBUG SQLDataSource - [builtinApplication.am_employee_current_search_fetch] Eval'd row count query: SELECT COUNT(*) FROM sdm$vi_web_employee_current
      				left join sdm$vi_web_unit_attribute on uat_emp_id = emp_id and
      				trunc(sysdate) between uat_valid_from and uat_valid_to WHERE 
      			(1=1 or uat_att_id = -1)
      				and (((LOWER(sdm$vi_web_employee_current.emi_last_name) LIKE LOWER('müller%') {ESCAPE '\'} AND sdm$vi_web_employee_current.emi_last_name IS NOT NULL) AND ((sdm$vi_web_employee_current.uni_1_name IS NULL) OR NOT(sdm$vi_web_employee_current.uni_1_name LIKE 'Ausg%' {ESCAPE '\'} AND sdm$vi_web_employee_current.uni_1_name IS NOT NULL))))
      			
      === 2011-02-15 10:48:01,023 [0-19] INFO  SQLDriver - [builtinApplication.am_employee_current_search_fetch] Executing SQL query on 'Oracle': SELECT COUNT(*) FROM sdm$vi_web_employee_current
      				left join sdm$vi_web_unit_attribute on uat_emp_id = emp_id and
      				trunc(sysdate) between uat_valid_from and uat_valid_to WHERE 
      			(1=1 or uat_att_id = -1)
      				and (((LOWER(sdm$vi_web_employee_current.emi_last_name) LIKE LOWER('müller%') {ESCAPE '\'} AND sdm$vi_web_employee_current.emi_last_name IS NOT NULL) AND ((sdm$vi_web_employee_current.uni_1_name IS NULL) OR NOT(sdm$vi_web_employee_current.uni_1_name LIKE 'Ausg%' {ESCAPE '\'} AND sdm$vi_web_employee_current.uni_1_name IS NOT NULL))))
      			
      === 2011-02-15 10:48:01,991 [0-19] WARN  SQLDataSource - [builtinApplication.am_employee_current_search_fetch] DataSource 'am_employee_current_search', OperationBinding 'null: sqlPaging was explicitly specified as 'sqlLimit', but the underlying database (oracle) does not support SQL limit queries.  Falling back to 'jdbcScroll'
      === 2011-02-15 10:48:01,991 [0-19] DEBUG SQLDataSource - [builtinApplication.am_employee_current_search_fetch] JDBC driver windowed select rows 0->75, result size 75. Query: SELECT distinct sdm$vi_web_employee_current.uni_3_id, 
      						sdm$vi_web_employee_current.uni_2_name,
      						sdm$vi_web_employee_current.emi_organisation_unit, 
      						sdm$vi_web_employee_current.uni_1_name,sdm$vi_web_employee_current.emi_staff_identification, 
      						sdm$vi_web_employee_current.uni_4_id,sdm$vi_web_employee_current.emp_id, 
      						sdm$vi_web_employee_current.emi_first_name,sdm$vi_web_employee_current.uni_5_name, 
      						sdm$vi_web_employee_current.uni_2_id,sdm$vi_web_employee_current.uni_5_id, 
      						sdm$vi_web_employee_current.emi_costplace,sdm$vi_web_employee_current.uni_4_name, 
      						sdm$vi_web_employee_current.uni_1_id,sdm$vi_web_employee_current.uni_3_name, 
      						sdm$vi_web_employee_current.emp_is_locked,sdm$vi_web_employee_current.emi_last_name FROM sdm$vi_web_employee_current
      				left join sdm$vi_web_unit_attribute on uat_emp_id = emp_id and
      				trunc(sysdate) between uat_valid_from and uat_valid_to WHERE 
      			(1=1 or uat_att_id = -1)
      				and (((LOWER(sdm$vi_web_employee_current.emi_last_name) LIKE LOWER('müller%') {ESCAPE '\'} AND sdm$vi_web_employee_current.emi_last_name IS NOT NULL) AND ((sdm$vi_web_employee_current.uni_1_name IS NULL) OR NOT(sdm$vi_web_employee_current.uni_1_name LIKE 'Ausg%' {ESCAPE '\'} AND sdm$vi_web_employee_current.uni_1_name IS NOT NULL))))
      			 ORDER BY sdm$vi_web_employee_current.emi_last_name
      === 2011-02-15 10:48:03,022 [0-19] INFO  DSResponse - [builtinApplication.am_employee_current_search_fetch] DSResponse: List with 75 items
      === 2011-02-15 10:48:03,022 [0-19] DEBUG RequestContext - Setting headers to disable caching
      === 2011-02-15 10:48:03,022 [0-19] DEBUG RPCManager - Content type for RPC transaction: text/plain; charset=UTF-8
      === 2011-02-15 10:48:03,022 [0-19] DEBUG RequestContext - Getting output stream via servletResponse.getWriter()
      === 2011-02-15 10:48:03,022 [0-19] DEBUG DataSource - In DS.forName() for 'am_employee_current_search' with DSRequest: com.isomorphic.datasource.DSRequest@4424a3
      === 2011-02-15 10:48:03,022 [0-19] DEBUG DataSource - Creating instance of DataSource 'am_employee_current_search'
      === 2011-02-15 10:48:03,038 [0-19] DEBUG RPCManager - DMI response, dropExtraFields: true
      === 2011-02-15 10:48:03,054 [0-19] DEBUG DataSource - In DS.forName() for 'am_employee_current_search' with DSRequest: com.isomorphic.datasource.DSRequest@4424a3
      === 2011-02-15 10:48:03,054 [0-19] DEBUG DataSource - Creating instance of DataSource 'am_employee_current_search'
      === 2011-02-15 10:48:03,054 [0-19] DEBUG DataSource - In DS.forName() for 'integer' with DSRequest: com.isomorphic.datasource.DSRequest@4424a3
      === 2011-02-15 10:48:03,054 [0-19] DEBUG DataSource - In DS.forName() for 'text' with DSRequest: com.isomorphic.datasource.DSRequest@4424a3
      === 2011-02-15 10:48:03,054 [0-19] DEBUG SQLTransaction - Ending Oracle transaction "3500110"
      === 2011-02-15 10:48:03,101 [0-19] DEBUG RequestContext - Paths for request:

      Comment


        #4
        Hi,

        unfortunately, the problem still occurs using the latest version of Smart GWT (2.5, Power Edition).

        However, surprisingly it only occurs in some cases (like that one described above). For example, the following ListGrid with a different DataSource has a correct sorting behavior:


        ListGrid definition:
        Code:
        StyleableListGrid listGrid = new StyleableListGrid("userManager_" + ds);
        listGrid.setDataSource(DataSource.get(ds));
        listGrid.setCanEdit(false);
        listGrid.setCellHeight(22);
        listGrid.setAutoFetchData(false);
        listGrid.setShowFilterEditor(false);
        listGrid.setSelectionType(SelectionStyle.MULTIPLE);
        listGrid.setHeight100();
        
        ListGridField prtName = new ListGridField(Consts.F_PRT_NAME);
        ListGridField uniName = new ListGridField(Consts.F_UNI_NAME);
        listGrid.setFields(prtName, uniName);
        
        // sortFields contains Consts.F_PRT_NAME and Consts.F_UNI_NAME
        SortSpecifier[] initialSort = new SortSpecifier[sortFields.length];
        for (int i = 0; i < sortFields.length; i++) {
        	initialSort[i] = new SortSpecifier(sortFields[i],
        	SortDirection.ASCENDING);
        }
        listGrid.setInitialSort(initialSort);

        DataSource:
        Code:
        <DataSource ID="privilege" serverType="sql" tableName="vi_web_privilege">
        <fields>
        	<field name="pri_id" primaryKey="true" type="sequence" sequenceName="se_privilege" required="false" detail="true" />
        	<field name="pri_annotation" type="text" required="false" detail="true" />
        	<field name="pri_description" type="text" required="false" detail="true" />
        	<field name="pri_emp_id" type="integer" required="true" detail="true" />
        	<field name="pri_prt_id" type="integer" required="true"  detail="true" />
        	<field name="pri_uni_id" type="integer" required="false" detail="true" />
        	
        	<field name="prt_name" type="text" customSQL="true"
        			tableName="vi_web_privilege_type" required="false" detail="false" />
        	<field name="uni_name" type="text" customSQL="true"
        			tableName="vi_web_unit" required="false" detail="false" />
        </fields>
        
        <operationBindings>
        	<operationBinding operationType="fetch" customValueFields="prt_name, uni_name" customCriteriaFields="prt_name, uni_name">
        	<tableClause>vi_web_privilege inner join vi_web_privilege_type on pri_prt_id=prt_id
        				left join vi_web_unit on uni_id = pri_uni_id</tableClause>
        	</operationBinding>
        </operationBindings>
        </DataSource>

        DSRequest:
        Code:
        {
            "dataSource":"privilege", 
            "operationType":"fetch", 
            "componentId":"isc_StyleableListGrid_1", 
            "data":{
                "pri_emp_id":"9000"
            }, 
            "startRow":0, 
            "endRow":75, 
            "sortBy":[
                "prt_name", 
                "uni_name"
            ], 
            "textMatchStyle":"exact", 
            "resultSet":[ResultSet ID:isc_ResultSet_2 (created by: isc_StyleableListGrid_1)], 
            "callback":{
                "caller":[ResultSet ID:isc_ResultSet_2 (created by: isc_StyleableListGrid_1)], 
                "methodName":"fetchRemoteDataReply"
            }, 
            "willHandleError":true, 
            "showPrompt":true, 
            "prompt":"Suche Datensätze die den Kriterien entsprechen...", 
            "oldValues":{
                "pri_emp_id":"9000"
            }, 
            "clientContext":{
                "requestIndex":1
            }, 
            "requestId":"privilege$62711"
        }

        The only difference I can figure out is that in this case the sort fields come from a different table. However, I wonder if this can affect the sorting behavior!?

        Maybe you can give me a hint? I would very much appreciate your help.

        Comment


          #5
          Your problem could be unrelated. Can you show the complete server log for the request?

          Comment


            #6
            Hello,

            thank you for your reply.

            The following code snippets show the current ListGrid configuration, the respective DataSource definition, the RPC tab contents as well as the server logs for the ListGrid with faulty sorting behavior.

            Please note that the DSRequest rightly contains the two sort columns "emi_last_name" and "emi_first_name", but the SQL select statement only contains "emi_last_name" in the order clause ("ORDER BY sdm$vi_web_am_employee_current.emi_last_name").

            Obviously, the second sort field is discarded (but why?):
            "WARN DSRequest - getSortBy() called on dsRequest containing multiple sortBy fields, returning first in list."

            If more information is necessary, please let me know.



            ListGrid configuration:
            Code:
            employeeSelectionGrid.setCanEdit(false);
            employeeSelectionGrid.setShowAllRecords(false);
            employeeSelectionGrid.setCellHeight(22);
            employeeSelectionGrid.setDataSource(amEmployeeCurrentSearchDS);
            employeeSelectionGrid.setAutoFetchData(false);
            employeeSelectionGrid.setCanMultiSort(true);
            employeeSelectionGrid.setShowFilterEditor(false);
            employeeSelectionGrid.setSelectionType(SelectionStyle.SINGLE);
            SortSpecifier[] initialSort = new SortSpecifier[2];
            initialSort[0] = new SortSpecifier(
            	GeneratedFieldConsts.F_EMI_LAST_NAME, SortDirection.ASCENDING);
            initialSort[1] = new SortSpecifier(
            	GeneratedFieldConsts.F_EMI_FIRST_NAME, SortDirection.ASCENDING);
            employeeSelectionGrid.setInitialSort(initialSort);
            employeeSelectionGrid.setFilterOnKeypress(true);
            employeeSelectionGrid.setHeight100();
            employeeSelectionGrid.addRecordClickHandler(new RecordClickHandler() {
            			@Override
            			public void onRecordClick(RecordClickEvent event) {
            ...			
            }
            		});
            employeeSelectionGrid.setAlternateRecordStyles(true);

            DataSource and DMI:
            Code:
            <DataSource ID="am_employee_current_search" serverType="sql"
            	tableName="sdm$vi_web_am_employee_current" qulifyColumnNames="false" >
            	<fields>
            		<field name="emi_last_name" title="Nachname" type="text" />
            		<field name="emi_first_name" title="Vorname" type="text" />
            		<field name="emi_costplace" title="Kostenstelle" type="text" />
            		<field name="emi_staff_identification" title="Personalnummer"
            			type="text" />
            		<field name="emi_organisation_unit" title="Orgeinheit (SAP)"
            			type="text" />
            		<field name="uni_1_id" type="integer" detail="true" />
            		<field name="uni_2_id" type="integer" detail="true" />
            		<field name="uni_3_id" type="integer" detail="true" />
            		<field name="uni_4_id" type="integer" detail="true" />
            		<field name="uni_5_id" type="integer" detail="true" />
            		<field name="uni_1_name" title="Team" type="text" />
            		<field name="uni_2_name" title="Abteilung" type="text" detail="true" />
            		<field name="uni_3_name" title="CCM" type="text" detail="true" />
            		<field name="uni_4_name" title="Bereich" type="text" detail="true" />
            		<field name="uni_5_name" title="Mandant" type="text" detail="true" />
            		<field name="emp_id" type="integer" primaryKey="true" detail="true" />
            		<field name="emp_is_locked" type="integer" detail="true" />		
            	</fields>
            	<serverObject lookupStyle="new"
            		className="de.tmobile.sdom.frontend.server.dmi.AMEmployeeCurrentSearchDMI" />
            	<operationBindings>
            		<operationBinding operationType="fetch">
            			<whereClause>
            			<![CDATA[
            			#if( $att_id )]]>
            				#if( $att_needs_employee )
            					emp_id in (select uat_emp_id from sdm$vi_web_unit_attribute where uat_att_id=$att_id and trunc(sysdate) between uat_valid_from and uat_valid_to)
            				#elseif( $att_needs_value )
            					uni_1_id in (select uat_uni_id from sdm$vi_web_unit_attribute where uat_att_id=$att_id and uat_value=$att_value_text and trunc(sysdate) between uat_valid_from and uat_valid_to)
            				#else
            					uni_1_id in (select uat_uni_id from sdm$vi_web_unit_attribute where uat_att_id=$att_id and trunc(sysdate) between uat_valid_from and uat_valid_to)
            				#end
            				and
            			#end
            			($defaultWhereClause)
            			</whereClause>
            		</operationBinding>
            	</operationBindings>
            </DataSource>
            Code:
            public DSResponse fetch(DSRequest dsRequest) throws Exception {
            	DSResponse dsResponse = null;
            	Map parameters = dsRequest.getHttpServletRequest().getParameterMap();
            	Integer attId = ConvServer.toInt(parameters.get(Consts.F_ATT_ID));
            	if (attId != null) {
            		dsRequest.addToTemplateContext(Consts.F_ATT_ID, attId);
            		dsRequest.addToTemplateContext(Consts.F_ATT_NEEDS_EMPLOYEE,
            				ConvServer.toBool(parameters
            						.get(Consts.F_ATT_NEEDS_EMPLOYEE)));
            		dsRequest.addToTemplateContext(Consts.F_ATT_NEEDS_VALUE, ConvServer
            				.toBool(parameters.get(Consts.F_ATT_NEEDS_VALUE)));
            		dsRequest.addToTemplateContext(Consts.F_ATT_VALUE_TEXT, ConvServer
            				.toString(parameters.get(Consts.F_ATT_VALUE_TEXT)));
            	}
            	dsResponse = dsRequest.execute();
            	return dsResponse;
            }

            DSRequest (sortBy is correct):
            Code:
            {
                "dataSource":"am_employee_current_search", 
                "operationType":"fetch", 
                "componentId":"isc_AgentManagerTab_1_0", 
                "data":{
                    "operator":"and", 
                    "criteria":[
                        {
                            "fieldName":"emi_last_name", 
                            "operator":"iStartsWith", 
                            "value":"Müller"
                        }, 
                        {
                            "operator":"or", 
                            "criteria":[
                                {
                                    "fieldName":"uni_1_name", 
                                    "operator":"isNull"
                                }, 
                                {
                                    "fieldName":"uni_1_name", 
                                    "operator":"notStartsWith", 
                                    "value":"Ausg"
                                }
                            ]
                        }
                    ]
                }, 
                "startRow":0, 
                "endRow":75, 
                "sortBy":[
                    "emi_last_name", 
                    "emi_first_name"
                ], 
                "textMatchStyle":"exact", 
                "resultSet":[ResultSet ID:isc_ResultSet_3 (created by: isc_AgentManagerTab_1_0)], 
                "callback":{
                    "caller":[ResultSet ID:isc_ResultSet_3 (created by: isc_AgentManagerTab_1_0)], 
                    "methodName":"fetchRemoteDataReply"
                }, 
                "willHandleError":true, 
                "showPrompt":true, 
                "prompt":"Suche Datensätze die den Kriterien entsprechen...", 
                "oldValues":{
                    "operator":"and", 
                    "criteria":[
                        {
                            "fieldName":"emi_last_name", 
                            "operator":"iStartsWith", 
                            "value":"Müller"
                        }, 
                        {
                            "operator":"or", 
                            "criteria":[
                                {
                                    "fieldName":"uni_1_name", 
                                    "operator":"isNull"
                                }, 
                                {
                                    "fieldName":"uni_1_name", 
                                    "operator":"notStartsWith", 
                                    "value":"Ausg"
                                }
                            ]
                        }
                    ]
                }, 
                "clientContext":{
                    "requestIndex":3
                }, 
                "requestId":"am_employee_current_search$62738"
            }
            DSResponse (records are mixed up; correct order should have been "Müller, D.; Müller, K.; Müller, R.")
            Code:
            [
                {
                    endRow:75, 
                    queueStatus:0, 
                    totalRows:221, 
                    isDSResponse:true, 
                    invalidateCache:false, 
                    status:0, 
                    startRow:0, 
                    data:[
                        {
                            emi_first_name:"R…", 
                            emi_last_name:"Müller"
            …
                        }, 
                        {
                            emi_first_name:"D..", 
                            emi_last_name:"Müller"
            …
                        }, 
                        {
                            emi_first_name:"K..", 
                            emi_last_name:"Müller"
            …
                        },
            …
            ]
            Server logs:
            Code:
            === 2011-08-30 11:47:48,616 [l0-3] INFO  RequestContext - URL: '/frontend/sc/IDACall', User-Agent: 'Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20': Moz (Gecko) with Accept-Encoding header
            === 2011-08-30 11:47:48,618 [l0-3] DEBUG DataSource - In DS.forName() for 'transaction' with DSRequest: null
            === 2011-08-30 11:47:48,618 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,618 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,618 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,618 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,618 [l0-3] DEBUG DataSource - In DS.forName() for 'List' with DSRequest: null
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - Creating instance of DataSource 'List'
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - In DS.forName() for 'elem' with DSRequest: null
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - In DS.forName() for 'List' with DSRequest: null
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - Creating instance of DataSource 'List'
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,619 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - In DS.forName() for 'List' with DSRequest: null
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - Creating instance of DataSource 'List'
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - In DS.forName() for 'List' with DSRequest: null
            === 2011-08-30 11:47:48,620 [l0-3] DEBUG DataSource - Creating instance of DataSource 'List'
            === 2011-08-30 11:47:48,621 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,621 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,621 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,621 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,621 [l0-3] DEBUG DataSource - In DS.forName() for 'List' with DSRequest: null
            === 2011-08-30 11:47:48,621 [l0-3] DEBUG DataSource - Creating instance of DataSource 'List'
            === 2011-08-30 11:47:48,621 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,621 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,621 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,621 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - In DS.forName() for 'List' with DSRequest: null
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - Creating instance of DataSource 'List'
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - In DS.forName() for 'Object' with DSRequest: null
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - Creating instance of DataSource 'Object'
            === 2011-08-30 11:47:48,622 [l0-3] DEBUG DataSource - In DS.forName() for 'am_employee_current_search' with DSRequest: com.isomorphic.datasource.DSRequest@831414
            === 2011-08-30 11:47:48,623 [l0-3] DEBUG DataSource - Creating instance of DataSource 'am_employee_current_search'
            === 2011-08-30 11:47:48,623 [l0-3] INFO  AuthentificationIDACall - Performing 1 operation(s)
            === 2011-08-30 11:47:48,673 [l0-3] WARN  DSRequest - getSortBy() called on dsRequest containing multiple sortBy fields, returning first in list.
            === 2011-08-30 11:47:48,675 [l0-3] INFO  SQLDataSource - [builtinApplication.am_employee_current_search_fetch] Performing fetch operation with
            	criteria: {operator:"and",criteria:[{fieldName:"emi_last_name",operator:"iStartsWith",value:"Müller"},{operator:"or",criteria:[{fieldName:"uni_1_name",operator:"isNull"},{fieldName:"uni_1_name",operator:"notStartsWith",value:"Ausg"}]}],_constructor:"AdvancedCriteria"}	values: {operator:"and",criteria:[{fieldName:"emi_last_name",operator:"iStartsWith",value:"Müller"},{operator:"or",criteria:[{fieldName:"uni_1_name",operator:"isNull"},{fieldName:"uni_1_name",operator:"notStartsWith",value:"Ausg"}]}],_constructor:"AdvancedCriteria"}
            === 2011-08-30 11:47:48,675 [l0-3] INFO  SQLDataSource - [builtinApplication.am_employee_current_search_fetch] derived query: SELECT $defaultSelectClause FROM $defaultTableClause WHERE 
            			
            			#if( $att_id )
            				#if( $att_needs_employee )
            					emp_id in (select uat_emp_id from sdm$vi_web_unit_attribute where uat_att_id=$att_id and trunc(sysdate) between uat_valid_from and uat_valid_to)
            				#elseif( $att_needs_value )
            					uni_1_id in (select uat_uni_id from sdm$vi_web_unit_attribute where uat_att_id=$att_id and uat_value=$att_value_text and trunc(sysdate) between uat_valid_from and uat_valid_to)
            				#else
            					uni_1_id in (select uat_uni_id from sdm$vi_web_unit_attribute where uat_att_id=$att_id and trunc(sysdate) between uat_valid_from and uat_valid_to)
            				#end
            				and
            			#end
            			($defaultWhereClause)
            			 ORDER BY $defaultOrderClause
            === 2011-08-30 11:47:48,678 [l0-3] DEBUG SQLDataSource - [builtinApplication.am_employee_current_search_fetch] Executing row count query: SELECT COUNT(*) FROM $defaultTableClause WHERE 
            			
            			#if( $att_id )
            				#if( $att_needs_employee )
            					emp_id in (select uat_emp_id from sdm$vi_web_unit_attribute where uat_att_id=$att_id and trunc(sysdate) between uat_valid_from and uat_valid_to)
            				#elseif( $att_needs_value )
            					uni_1_id in (select uat_uni_id from sdm$vi_web_unit_attribute where uat_att_id=$att_id and uat_value=$att_value_text and trunc(sysdate) between uat_valid_from and uat_valid_to)
            				#else
            					uni_1_id in (select uat_uni_id from sdm$vi_web_unit_attribute where uat_att_id=$att_id and trunc(sysdate) between uat_valid_from and uat_valid_to)
            				#end
            				and
            			#end
            			($defaultWhereClause)
            			
            === 2011-08-30 11:47:48,678 [l0-3] DEBUG SQLDataSource - [builtinApplication.am_employee_current_search_fetch] Eval'd row count query: SELECT COUNT(*) FROM sdm$vi_web_am_employee_current WHERE 
            			
            						(((LOWER(sdm$vi_web_am_employee_current.emi_last_name) LIKE LOWER('müller%') {ESCAPE '\'} AND sdm$vi_web_am_employee_current.emi_last_name IS NOT NULL) AND ((sdm$vi_web_am_employee_current.uni_1_name IS NULL) OR NOT(sdm$vi_web_am_employee_current.uni_1_name LIKE 'Ausg%' {ESCAPE '\'} AND sdm$vi_web_am_employee_current.uni_1_name IS NOT NULL))))
            			
            === 2011-08-30 11:47:48,679 [l0-3] INFO  SQLDriver - [builtinApplication.am_employee_current_search_fetch] Executing SQL query on 'Oracle': SELECT COUNT(*) FROM sdm$vi_web_am_employee_current WHERE 
            			
            						(((LOWER(sdm$vi_web_am_employee_current.emi_last_name) LIKE LOWER('müller%') {ESCAPE '\'} AND sdm$vi_web_am_employee_current.emi_last_name IS NOT NULL) AND ((sdm$vi_web_am_employee_current.uni_1_name IS NULL) OR NOT(sdm$vi_web_am_employee_current.uni_1_name LIKE 'Ausg%' {ESCAPE '\'} AND sdm$vi_web_am_employee_current.uni_1_name IS NOT NULL))))
            			
            === 2011-08-30 11:47:48,786 [l0-2] INFO  RequestContext - URL: '/frontend/sc/system/reference/skin/images/server_client_exchange.png', User-Agent: 'Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20': Moz (Gecko) with Accept-Encoding header
            === 2011-08-30 11:47:50,653 [l0-3] WARN  SQLDataSource - [builtinApplication.am_employee_current_search_fetch] DataSource 'am_employee_current_search', OperationBinding 'null: sqlPaging was explicitly specified as 'sqlLimit', but the underlying database (oracle) does not support SQL limit queries.  Falling back to 'jdbcScroll'
            === 2011-08-30 11:47:50,653 [l0-3] DEBUG SQLDataSource - [builtinApplication.am_employee_current_search_fetch] JDBC driver windowed select rows 0->75, result size 75. Query: SELECT sdm$vi_web_am_employee_current.uni_3_id, sdm$vi_web_am_employee_current.uni_2_name, sdm$vi_web_am_employee_current.emi_organisation_unit, sdm$vi_web_am_employee_current.uni_1_name, sdm$vi_web_am_employee_current.emi_staff_identification, sdm$vi_web_am_employee_current.uni_4_id, sdm$vi_web_am_employee_current.emp_id, sdm$vi_web_am_employee_current.emi_first_name, sdm$vi_web_am_employee_current.uni_5_name, sdm$vi_web_am_employee_current.uni_2_id, sdm$vi_web_am_employee_current.uni_5_id, sdm$vi_web_am_employee_current.emi_costplace, sdm$vi_web_am_employee_current.uni_4_name, sdm$vi_web_am_employee_current.uni_1_id, sdm$vi_web_am_employee_current.uni_3_name, sdm$vi_web_am_employee_current.emp_is_locked, sdm$vi_web_am_employee_current.emi_last_name FROM sdm$vi_web_am_employee_current WHERE 
            			
            						(((LOWER(sdm$vi_web_am_employee_current.emi_last_name) LIKE LOWER('müller%') {ESCAPE '\'} AND sdm$vi_web_am_employee_current.emi_last_name IS NOT NULL) AND ((sdm$vi_web_am_employee_current.uni_1_name IS NULL) OR NOT(sdm$vi_web_am_employee_current.uni_1_name LIKE 'Ausg%' {ESCAPE '\'} AND sdm$vi_web_am_employee_current.uni_1_name IS NOT NULL))))
            			 ORDER BY sdm$vi_web_am_employee_current.emi_last_name
            === 2011-08-30 11:47:54,634 [l0-3] INFO  DSResponse - [builtinApplication.am_employee_current_search_fetch] DSResponse: List with 75 items
            === 2011-08-30 11:47:54,636 [l0-3] DEBUG DataSource - In DS.forName() for 'am_employee_current_search' with DSRequest: com.isomorphic.datasource.DSRequest@831414
            === 2011-08-30 11:47:54,636 [l0-3] DEBUG DataSource - Creating instance of DataSource 'am_employee_current_search'
            === 2011-08-30 11:47:54,637 [l0-3] DEBUG DataSource - In DS.forName() for 'integer' with DSRequest: com.isomorphic.datasource.DSRequest@831414
            === 2011-08-30 11:47:54,638 [l0-3] DEBUG DataSource - In DS.forName() for 'text' with DSRequest: com.isomorphic.datasource.DSRequest@831414
            === 2011-08-30 11:47:55,598 [l0-3] INFO  RequestContext - URL: '/frontend/sc/system/reference/skin/images/server_client_exchange.png', User-Agent: 'Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20': Moz (Gecko) with Accept-Encoding header
            Last edited by jafr; 30 Aug 2011, 02:02.

            Comment


              #7
              Please ignore post #4. In that case, the second sort field is omitted in the SQL order clause as well. However, client-side sorting seems to be performed:

              Code:
              16:31:24.856:XRP3:INFO:ResultSet:isc_ResultSet_1 (created by: isc_StyleableListGrid_1):$391: sorting on properties [prt_name,uni_name] : directions [true,true] : full cache allows local sort"

              Comment


                #8
                We have tried to reproduce this problem but have been unable to. The test case we tried was closely based on yours: the client-side code and DataSource definition were identical (but see below), a DMI was used, and Oracle was the database in use. What we see is what you would expect: an ORDER BY clause that contains both fields. This test was done with the SmartGWT 2.5 Eval nightly dated 31 August.

                Note that one thing we had to change was the table name - when we tried to use "sdm$vi_web_am_employee_current", the import failed with the error message: "java.sql.SQLException: ORA-00972: identifier is too long". So our test used table name "sdm$employee_current"; it hardly seems likely that this could have made a difference.

                So, we cannot investigate this further without a complete, self-contained example that demonstrates the problem.

                Comment


                  #9
                  Hi,
                  thank you for your efforts to reproduce our problem!
                  I have now created a very basic test case which demonstrates the problem. It is based on an Oracle system table, so it should be easily transferable.


                  First of all, there is a Tab which contains the ListGrid:
                  Code:
                  public class SortTestTab extends Tab {
                  
                  	public SortTestTab() {
                  
                  		setTitle("SortTest");
                  		setCanClose(true);
                  
                  		ListGrid sortTestGrid = new ListGrid();
                  		sortTestGrid.setCanEdit(false);
                  		sortTestGrid.setShowAllRecords(false);
                  		sortTestGrid.setCellHeight(22);
                  		sortTestGrid.setDataSource(DataSource.get("sort_test"));
                  		sortTestGrid.setAutoFetchData(true);
                  		sortTestGrid.setCanMultiSort(true);
                  		sortTestGrid.setShowFilterEditor(false);
                  		sortTestGrid.setSelectionType(SelectionStyle.SINGLE);
                  		SortSpecifier[] initialSort = new SortSpecifier[2];
                  		initialSort[0] = new SortSpecifier("tabtype", SortDirection.ASCENDING);
                  		initialSort[1] = new SortSpecifier("tname", SortDirection.ASCENDING);
                  		sortTestGrid.setInitialSort(initialSort);
                  		sortTestGrid.setHeight100();
                  		sortTestGrid.setAlternateRecordStyles(true);
                  
                  		setPane(sortTestGrid);
                  	}
                  }

                  The DataSource looks as follows:
                  Code:
                  <DataSource ID="sort_test" serverType="sql" tableName="sys.tab">
                  	<fields>
                  		<field name="tabtype" type="text" />
                  		<field name="tname" type="text" />
                  	</fields>
                  </DataSource>

                  DSRequest (seems to be correct)
                  Code:
                  {
                      "dataSource":"sort_test", 
                      "operationType":"fetch", 
                      "componentId":"isc_ListGrid_0", 
                      "data":{
                      }, 
                      "startRow":0, 
                      "endRow":75, 
                      "sortBy":[
                          "tabtype", 
                          "tname"
                      ], 
                      "textMatchStyle":"substring", 
                      "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":{
                      }, 
                      "clientContext":{
                          "requestIndex":1
                      }, 
                      "requestId":"sort_test$6277"
                  }
                  And finally, the server logs (please note that getSortBy() triggers a WARN message and only "tabtype" is included in the ORDER BY clause):
                  Code:
                  === 2011-09-01 12:51:41,318 [0-17] INFO  RequestContext - URL: '/frontend/sc/IDACall', User-Agent: 'Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20': Moz (Gecko) with Accept-Encoding header
                  === 2011-09-01 12:51:41,320 [0-17] INFO  AuthentificationIDACall - Performing 1 operation(s)
                  === 2011-09-01 12:51:41,366 [0-17] WARN  DSRequest - getSortBy() called on dsRequest containing multiple sortBy fields, returning first in list.
                  === 2011-09-01 12:51:41,367 [0-17] INFO  SQLDataSource - [builtinApplication.sort_test_fetch] Performing fetch operation with
                  	criteria: {}	values: {}
                  === 2011-09-01 12:51:41,367 [0-17] INFO  SQLWhereClause - [builtinApplication.sort_test_fetch] empty condition
                  === 2011-09-01 12:51:41,367 [0-17] INFO  SQLDataSource - [builtinApplication.sort_test_fetch] derived query: SELECT $defaultSelectClause FROM $defaultTableClause WHERE $defaultWhereClause ORDER BY $defaultOrderClause
                  === 2011-09-01 12:51:41,367 [0-17] DEBUG SQLDataSource - [builtinApplication.sort_test_fetch] Executing row count query: SELECT COUNT(*) FROM $defaultTableClause WHERE $defaultWhereClause
                  === 2011-09-01 12:51:41,367 [0-17] DEBUG SQLDataSource - [builtinApplication.sort_test_fetch] Eval'd row count query: SELECT COUNT(*) FROM sys.tab WHERE ('1'='1')
                  === 2011-09-01 12:51:41,367 [0-17] INFO  SQLDriver - [builtinApplication.sort_test_fetch] Executing SQL query on 'cti_sdom_apps': SELECT COUNT(*) FROM sys.tab WHERE ('1'='1')
                  === 2011-09-01 12:51:41,390 [0-17] WARN  SQLDataSource - [builtinApplication.sort_test_fetch] DataSource 'sort_test': sqlPaging was explicitly specified as 'sqlLimit', but the underlying database (oracle) does not support SQL limit queries.  Falling back to 'jdbcScroll'
                  === 2011-09-01 12:51:41,390 [0-17] DEBUG SQLDataSource - [builtinApplication.sort_test_fetch] JDBC driver windowed select rows 0->75, result size 75. Query: SELECT sys.tab.tname, sys.tab.tabtype FROM sys.tab WHERE ('1'='1') ORDER BY sys.tab.tabtype
                  === 2011-09-01 12:51:41,412 [0-17] INFO  DSResponse - [builtinApplication.sort_test_fetch] DSResponse: List with 75 items

                  We use the stable version (no nightly build) of Smart GWT 2.5 (power edition) in combination with GWT 2.3. The tested browser is Firefox 3.6.20. The Oracle version is 10G Release 2.
                  Last edited by jafr; 1 Sep 2011, 03:04.

                  Comment


                    #10
                    Do you have any new hints for us? We are still facing the sorting problem.

                    Comment


                      #11
                      Have you tried this test case in an unmodified SDK? We've already tried to reproduce the problem and couldn't with a similar test, so we want to make sure you've created a truly standalone test rather than just simplified code that is still running in your existing application, where code not shown in the test case could still be involved.

                      Comment


                        #12
                        OK, we tried again with this simplified test case and your exact reported config, and again we see correct behavior. Please try what we did - download the official SGWT 2.5 release from the website and then apply your example code to one of the built-in samples, keeping everything completely separate from your actual project. You will see that the problem does not show itself in a clean test.

                        Given this, it seems most likely that you have somehow got server JARs from an older build mixed into your project.

                        Comment


                          #13
                          Thank you again for your efforts!

                          I've just realized that I must have overlooked two lines of code before which are causing the described problem.

                          For all requests handled by the IDACall servlet we do some kind of filtering to avoid SQL injection. Amongst others, we do this:

                          Code:
                          String sortBy = request.getSortBy();
                          request.setSortBy(HTMLFilter.replaceHtmlSpecialChars(sortBy));
                          Here, the call to getSortBy() only returns the first sort column, as posted above in the server logs:
                          Code:
                          WARN  DSRequest - getSortBy() called on dsRequest containing multiple sortBy fields, returning first in list.
                          According to the Javadocs for the com.isomorphic.datasource.DSRequest class (latest nightly build), getSortBy() should not exist at all and has obviously been replaced by getSortByFields().

                          If I use this method in the filter, the sorting works as expected.


                          Maybe, getSortBy() should be removed completely from the DSRequest class to avoid possible inconsistencies and confusion?

                          Comment

                          Working...
                          X