Announcement

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

    ListGride Datasource with Composite Primary Key

    I have a hibernate Datasource in a simple ListGrid. The Datasource has a composite primary key. Whenever I try to make updates or add new rows I got an error message:

    Criteria received from the client for add operation is missing the following non-sequence primary key fields: [hardwareTypePK.hdwTypeId, hardwareTypePK.locale]. Either provide all primary key fields that are not sequences, or set allowMultiUpdate on the OperationBinding
    Here's my Datasource file:
    Code:
    <DataSource ID="HardwareType" serverType="hibernate"
        beanClassName="com.assaabloy.aaos.shared.entities.aaos.HardwareType"
        configBean="aaosSessionFactory">
        <fields>
            <field name="hardwareTypePK.hdwTypeId" type="text" title="Hardware Type"
                primaryKey="true" />
            <field name="hardwareTypePK.locale" type="text" hidden="true"
                primaryKey="true" />
            <field name="nativeType" type="text" />
            <field name="description" type="text" />
            <field name="sortOrder" type="integer" />
        </fields>
    </DataSource>
    I'm looking at the request in the developer console and both fields for the primary key are there. Here's the request:
    Code:
    {
        dataSource:"HardwareType", 
        operationType:"add", 
        componentId:"isc_ListGrid_1", 
        data:{
            hardwareTypePK:{
                locale:"en_US", 
                hdwTypeId:"ds"
            }, 
            nativeType:"ds", 
            description:"asdf", 
            sortOrder:40
        }, 
        textMatchStyle:"exact", 
        callback:"isc_ListGrid_1.$337(dsResponse, dsRequest)", 
        willHandleError:true, 
        showPrompt:false, 
        oldValues:{
            hardwareTypePK:{
                locale:"en_US", 
                hdwTypeId:"ds"
            }, 
            nativeType:"ds", 
            description:"asdf", 
            sortOrder:40
        }, 
        requestId:"HardwareType$6273", 
        internalClientContext:{
            saveCallback:{
            }, 
            newValues:{
                hardwareTypePK:Obj, 
                nativeType:"ds", 
                description:"asdf", 
                sortOrder:40
            }, 
            editInfo:{
                editValuesID:"_0", 
                rowNum:35, 
                colNum:3, 
                values:Obj, 
                editCompletionEvent:"enter"
            }
        }, 
        fallbackToEval:false, 
        lastClientEventThreadCode:"KPR4", 
        bypassCache:true, 
        dataProtocol:"getParams"
    }
    I also tried setting the allowMultiUpdate in the operation binding, but that gave me another message that the primary key was null. Is there something I'm doing wrong?

    #2
    Hi,

    Please try removing the prefix "hardwareTypePK." from the fields' name attributes.

    Best regards
    Blama

    Comment


      #3
      If I take those away then I don't get any data returned to the ListGrid. Here's a sample of the response from the fetch:
      Code:
       data:[
              {
                  attrType6Id:null, 
                  attrType4Id:null, 
                  attrType5Id:null, 
                  attrType2Id:null, 
                  attrType3Id:null, 
                  attrType1Id:null, 
                  nativeType:"BO", 
                  sortOrder:1, 
                  description:"Bolts", 
                  hardwareTypePK:{
                      hdwTypeId:"07", 
                      locale:"en_BE"
                  }
              },
      I retried this using the autoDeriveSchema property on the DataSource and that makes the fetch look like this:
      Code:
      data:[
              {
                  hardwareTypePK_hdwTypeId:"07", 
                  hardwareTypePK_locale:"en_BE", 
                  attrType6Id:null, 
                  attrType4Id:null, 
                  attrType5Id:null, 
                  attrType2Id:null, 
                  attrType3Id:null, 
                  attrType1Id:null, 
                  nativeType:"BO", 
                  sortOrder:1, 
                  description:"Bolts", 
                  hardwareTypePK:{
                      hdwTypeId:"07", 
                      locale:"en_BE"
                  }
              },
      I've read in the documentation that composite keys are supported, which they obviously are because the autoDeriveSchema works. But if I want to call out my own list of fields that are displayed, how do I denote the primary keys?

      Comment


        #4
        Hi,

        see the 2nd data[]. You can see "hardwareTypePK_hdwTypeId" there. Try using this in your Java ListGrid ListGridField definition.
        Last lines in the 2nd data[] is most likely because you left the .ds.xml in place.

        See here why your approach is definitely wrong (name-attribute building rules).

        Best regards
        Blama

        Comment


          #5
          Thanks for your help on this, I really appreciate it. But I'm still not quite sure why this doesn't work:

          This displays the data correctly, but doesn't allow me to save/udpate:
          Code:
          <DataSource ID="HardwareType" serverType="hibernate"
              beanClassName="com.assaabloy.aaos.shared.entities.aaos.HardwareType"
              configBean="aaosSessionFactory"> 
              <fields>
                  <field name="hardwareTypePK.hdwTypeId" type="text" title="Hardware Type" primaryKey="true" />
                  <field name="hardwareTypePK.locale" type="text" hidden="true" primaryKey="true" />
                  <field name="nativeType" type="text" />
                  <field name="description" type="text" />
                  <field name="sortOrder" type="integer" />
              </fields>
          </DataSource>

          This loads data in every field except for the primary key fields, and doesn't allow me to save/udpate:
          Code:
          <DataSource ID="HardwareType" serverType="hibernate"
              beanClassName="com.assaabloy.aaos.shared.entities.aaos.HardwareType"
              configBean="aaosSessionFactory"> 
              <fields>
                  <field name="hdwTypeId" type="text" title="Hardware Type" primaryKey="true" />
                  <field name="locale" type="text" hidden="true" primaryKey="true" />
                  <field name="nativeType" type="text" />
                  <field name="description" type="text" />
                  <field name="sortOrder" type="integer" />
              </fields>
          </DataSource>
          This works, but shows all fields:
          Code:
          <DataSource ID="HardwareType" serverType="hibernate"
              autoDeriveSchema="true"
              schemaBean="com.assaabloy.aaos.shared.entities.aaos.HardwareType"
              beanClassName="com.assaabloy.aaos.shared.entities.aaos.HardwareType"
              configBean="aaosSessionFactory"> 
          </DataSource>
          Tried with the underscores just for kicks, doesn't work:
          Code:
          <DataSource ID="HardwareType" serverType="hibernate"
              beanClassName="com.assaabloy.aaos.shared.entities.aaos.HardwareType"
              configBean="aaosSessionFactory"> 
              <fields>
                  <field name="hardwareTypePK_hdwTypeId" type="text" title="Hardware Type" primaryKey="true" />
                  <field name="hardwareTypePK_locale" type="text" hidden="true" primaryKey="true" />
                  <field name="nativeType" type="text" />
                  <field name="description" type="text" />
                  <field name="sortOrder" type="integer" />
              </fields>
          </DataSource>
          I'm just looking to hide fields, add validators, etc, but apparently I'm not calling the fields out correctly in the xml.

          Comment


            #6
            Hi,

            for the names to be 100% sure you can use autoDeriveSchema like you did and then use this as base for your .ds.xml.
            According to #3 this should be what you are showing in #5 as last block.
            If you are really sure that this does not work I have no idea.

            Could you post the data from the Developer Console RPC Tab you get for the last config?
            You are not setting any fields on the ListGrid yourself, are you? Just myLG.setDataSource() and then fetch()?

            Best regards
            Blama


            Comment


              #7
              Ok, I added the autoDerive back and used the underscores:
              Code:
              <DataSource ID="HardwareType" serverType="hibernate"
                  autoDeriveSchema="true"
                  schemaBean="com.assaabloy.aaos.shared.entities.aaos.HardwareType"
                  beanClassName="com.assaabloy.aaos.shared.entities.aaos.HardwareType"
                  configBean="aaosSessionFactory">
                  <fields>
                      <field name="hardwareTypePK_hdwTypeId" type="text" title="Hardware Type" primaryKey="true" />
                      <field name="hardwareTypePK_locale" type="text" hidden="true" primaryKey="true" />
                      <field name="nativeType" type="text" />
                      <field name="description" type="text" />
                      <field name="sortOrder" type="integer" />
                  </fields>
              </DataSource>
              The data doesn't display in the primary key columns, and save/update doesn't work, still complains about keys missing.

              Here's the fetch data using the above config:
              Code:
              data:[
                      {
                          attrType6Id:null, 
                          attrType4Id:null, 
                          attrType5Id:null, 
                          attrType2Id:null, 
                          attrType3Id:null, 
                          attrType1Id:null, 
                          nativeType:"BO", 
                          sortOrder:1, 
                          description:"Bolts", 
                          hardwareTypePK:{
                              hdwTypeId:"07", 
                              locale:"en_BE"
                          }
                      },
              I'm still curious why using the dots vs underscores displays data correctly, but then can't save that same data.

              Comment


                #8
                OK, I really find this strange.
                You should post your exact version just and wait for Isomorphic.

                Best regards
                Blama

                Comment


                  #9
                  We agree, this doesn't make sense - sorry we suspect that you've got mixed up reporting configuration and results.

                  If autoDeriveSchema caused the PK values to appear with underscores in the data, then it should be the case that declaring those same fields, with underscore names, works. Please retry that configuration and be sure that you don't have any unsaved changes or caches that might mean you are looking at stale information.

                  Comment


                    #10
                    I tried this again, no luck. Here's what I'm running:

                    Version:
                    Code:
                    INFO  ISCInit - Isomorphic SmartClient/SmartGWT Framework (v11.0p_2017-02-17/Pro Deployment 2017-02-17) - Initialization Complete
                    ds.xml
                    Code:
                    <DataSource ID="HardwareType" serverType="hibernate"
                        autoDeriveSchema="true"
                        schemaBean="com.assaabloy.aaos.shared.entities.aaos.HardwareType"
                        beanClassName="com.assaabloy.aaos.shared.entities.aaos.HardwareType"
                        configBean="aaosSessionFactory">
                        <fields>
                            <field name="hardwareTypePK_hdwTypeId" type="text" title="Hardware Type" primaryKey="true" />
                            <field name="hardwareTypePK_locale" type="text" hidden="true" primaryKey="true" />
                            <field name="nativeType" type="text" />
                            <field name="description" type="text" />
                            <field name="sortOrder" type="integer" />
                        </fields>
                    </DataSource>
                    ListGrid code:
                    Code:
                            listGrid = new ListGrid(DataSource.get(dataSourceID));
                            listGrid.setAlternateRecordStyles(true);
                            listGrid.setCanEdit(true);
                            listGrid.setCanRemoveRecords(canAddRemoveRows);
                            listGrid.setDataFetchMode(FetchMode.LOCAL);
                            listGrid.setAutoFetchData(true);
                            listGrid.setShowFilterEditor(true);
                            addMember(listGrid);
                    Console output from generating data source (new lines added for clarity):
                    Code:
                    Generated data source configuration: 
                    {idClassName=com.assaabloy.aaos.shared.entities.aaos.HardwareTypePK, 
                    beanClassName=com.assaabloy.aaos.shared.entities.aaos.HardwareType, 
                    entityName=com.assaabloy.aaos.shared.entities.aaos.HardwareType, 
                    serverType=hibernate, 
                    extIsEmbeddedId=true, 
                    allowAdvancedCriteria=true, 
                    ID=HardwareType, 
                    dropExtraFields=true, 
                    generatedBy=v11.0p_2017-02-17/Pro Deployment 2017-02-17, 
                    fields=[
                    {extPrecision=19, extIsLazy=false, canEdit=true, name=hardwareTypePK_hdwTypeId, length=100, extIsUnique=false, valueXPath=hardwareTypePK/hdwTypeId, type=text, extScale=2, required=true, primaryKey=true}, 
                    {extPrecision=19, extIsLazy=false, canEdit=true, name=hardwareTypePK_locale, length=50, extIsUnique=false, valueXPath=hardwareTypePK/locale, type=text, extScale=2, required=true, primaryKey=true}, 
                    {extPrecision=19, extIsLazy=false, canEdit=true, name=attrType1Id, length=255, extIsUnique=false, type=integer, extScale=2, required=false}, 
                    {extPrecision=19, extIsLazy=false, canEdit=true, name=attrType2Id, length=255, extIsUnique=false, type=integer, extScale=2, required=false}, 
                    {extPrecision=19, extIsLazy=false, canEdit=true, name=attrType3Id, length=255, extIsUnique=false, type=integer, extScale=2, required=false}, 
                    {extPrecision=19, extIsLazy=false, canEdit=true, name=attrType4Id, length=255, extIsUnique=false, type=integer, extScale=2, required=false}, 
                    {extPrecision=19, extIsLazy=false, canEdit=true, name=attrType5Id, length=255, extIsUnique=false, type=integer, extScale=2, required=false}, 
                    {extPrecision=19, extIsLazy=false, canEdit=true, name=attrType6Id, length=255, extIsUnique=false, type=integer, extScale=2, required=false}, 
                    {extPrecision=19, extIsLazy=false, canEdit=true, name=description, length=200, extIsUnique=false, type=text, extScale=2, required=false}, 
                    {extPrecision=19, extIsLazy=false, canEdit=true, name=nativeType, length=100, extIsUnique=false, type=text, extScale=2, required=false}, 
                    {extPrecision=19, extIsLazy=false, canEdit=true, name=sortOrder, length=255, extIsUnique=false, type=integer, extScale=2, required=false}]}
                    Developer console fetch response (first row of data):
                    Code:
                    data:[
                            {
                                attrType6Id:null, 
                                attrType4Id:null, 
                                attrType5Id:null, 
                                attrType2Id:null, 
                                attrType3Id:null, 
                                attrType1Id:null, 
                                nativeType:"BO", 
                                sortOrder:1, 
                                description:"Bolts", 
                                hardwareTypePK:{
                                    hdwTypeId:"07", 
                                    locale:"en_BE"
                                }
                            },
                    Error message on update:
                    Criteria received from the client for update operation is missing the following required unique and/or primary fields: [hardwareTypePK_hdwTypeId, hardwareTypePK_locale, hardwareTypePK_hdwTypeId, hardwareTypePK_locale]. Either provide all primary key fields or set allowMultiUpdate or providesMissingKeys on the OperationBinding (see the client-side docs for details of those flags
                    Developer console update request:
                    Code:
                    {
                        dataSource:"HardwareType", 
                        operationType:"update", 
                        componentId:"isc_ListGrid_1", 
                        data:{
                            description:"asdfasdf"
                        }, 
                        textMatchStyle:"exact", 
                        callback:"isc_ListGrid_1.$337(dsResponse, dsRequest)", 
                        willHandleError:true, 
                        showPrompt:false, 
                        oldValues:{
                            attrType6Id:null, 
                            attrType4Id:null, 
                            attrType5Id:null, 
                            attrType2Id:11, 
                            attrType3Id:3, 
                            attrType1Id:8, 
                            nativeType:"SL", 
                            sortOrder:2, 
                            description:"Sliding Door Hardware", 
                            hardwareTypePK:{
                                hdwTypeId:"SL", 
                                locale:"en_VN"
                            }
                        }, 
                        requestId:"HardwareType$6272", 
                        internalClientContext:{
                            saveCallback:{
                            }, 
                            newValues:{
                                description:"asdfasdf"
                            }, 
                            editInfo:{
                                editValuesID:"_0", 
                                rowNum:15, 
                                colNum:2, 
                                values:Obj, 
                                oldValues:Obj, 
                                editCompletionEvent:"enter"
                            }
                        }, 
                        fallbackToEval:false, 
                        dataFetchMode:"local", 
                        lastClientEventThreadCode:"KPR4", 
                        bypassCache:true, 
                        dataProtocol:"getParams"
                    }
                    I attached a screen image, the primary key column comes up blank.
                    Click image for larger version

Name:	2017-02-17_10-14-41.png
Views:	537
Size:	36.6 KB
ID:	242925

                    I've verified there aren't any other unsaved changes or caches. I'm starting the program (which only loads this ListGrid) right now, then trying to make an update to one of the fields. No other code or anything is happening, just getting started on this project.

                    Comment


                      #11
                      Isomorphic,

                      From what I can tell everything is set up correctly.

                      I'm wondering if this is a bug. Why does using the dot notation instead of underscores read data correctly but isn't able to save the data back?

                      Comment


                        #12
                        Here are some explanations:

                        Naming fields with dot notation (incorrect) works in fetching data because of server side internals "side effect" - value is accessed via bean notation.

                        When you use auto-derive field names are created like this: "compositePKPropertyNameInMainClass" + "_" + "propertyNameInCompositePK".
                        So you get "hardwareTypePK_hdwTypeId" where
                        "hardwareTypePK" property name for compositePK in class com.assaabloy.aaos.shared.entities.aaos.HardwareType and
                        "hdwTypeId" property name in class com.assaabloy.aaos.shared.entities.aaos.HardwareTypePK

                        Actual value access is done via "valueXPath" setting (in this case "valueXPath=hardwareTypePK/hdwTypeId")

                        All properties have to have public getters/setters.

                        Regards,
                        Alius

                        Comment

                        Working...
                        X