Announcement

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

    isUnique validator and cacheSyncOperation

    SmartClient Version: SNAPSHOT_v11.1d_2017-02-28/Enterprise Development Only (built 2017-02-28)

    Hello, I've got a isUnique validator, and I've just noticed that, while doing an update with an operationBinding which specifies a cacheSyncOperation, the latter isn't used for the automatic fetch done for the isUnique validation, but instead the default fetch is used.

    Is it intended behavior? Actually I was expecting the same operationId used for cache synchronization. So, I think I've found a bug.

    Otherwise, it would be useful to specify an operationId for the automatic fetch.

    #2
    We think it's probably not correct to use the cacheSyncOperation - that could be there for a totally different purpose, including no-oping for performance reasons. But we agree that it would be useful to be able to specify an operationId on the validator, and we will add that, as a new feature on the 11.1 branch only. We will post back on this thread when that has been done.

    Comment


      #3
      We have now added this to 11.1 / 6.1. Please check out tomorrow's nightly builds - look for Validator.operationId in the docs.

      Comment


        #4
        SmartClient Version: SNAPSHOT_v11.1d_2017-03-23/Enterprise Development Only (built 2017-03-23)

        Hello, thank you very much, it's working, but I'm facing another problem.
        I've got a isUnique validator with a criteriaFields attribute, like this:
        Code:
                <field sqlType="varchar" name="PLACEHOLDER" length="255" type="text">
                    <validators>
                        <validator type="isUnique" criteriaFields="ID_APP" errorMessage="PlaceHolder già presente per l'applicazione inserita" operationId="fetchDefault"/>
                    </validators>
                </field>
        but when there's an add operation where ID_APP is not set, I was expecting that it would be used as null in the automatic fetch, instead it is ignored:

        Code:
        2017-03-24 11:41:47,376 DEBUG DSRequest Caching instance 9667 of DS 'JRTE_METADATA' from DSRequest.getDataSource()
        2017-03-24 11:41:47,376 DEBUG DSRequest Caching instance 9667 of DS JRTE_METADATA
        2017-03-24 11:41:47,376 DEBUG RPCManager Request #1 (DSRequest) payload: {
            values:{
                NOME_GRUPPO:"sdf",
                NOME:"sdfsd",
                DESCRIZIONE:"dfds",
                DATASOURCE_ID:"sf",
                DS_FIELD:"sdf",
                PLACEHOLDER:"{{today_ora}}"
            },
            operationConfig:{
                dataSource:"JRTE_METADATA",
                repo:null,
                operationType:"add",
                textMatchStyle:"exact"
            },
            componentId:"configurazioneParametriTestiGridParametri",
            appID:"builtinApplication",
            operation:"JRTE_METADATA_add",
            oldValues:{
                NOME_GRUPPO:"sdf",
                NOME:"sdfsd",
                DESCRIZIONE:"dfds",
                DATASOURCE_ID:"sf",
                DS_FIELD:"sdf",
                PLACEHOLDER:"{{today_ora}}"
            },
            criteria:{
            }
        }
        2017-03-24 11:41:47,376 INFO  IDACall Performing 1 operation(s)
        2017-03-24 11:41:47,376 DEBUG DeclarativeSecurity Processing security checks for DataSource null, field null
        2017-03-24 11:41:47,376 DEBUG DeclarativeSecurity DataSource JRTE_METADATA is not in the pre-checked list, processing...
        2017-03-24 11:41:47,376 DEBUG AppBase [builtinApplication.JRTE_METADATA_add] No userTypes defined, allowing anyone access to all operations for this application
        2017-03-24 11:41:47,376 DEBUG AppBase [builtinApplication.JRTE_METADATA_add] No public zero-argument method named '_JRTE_METADATA_add' found, performing generic datasource operation
        2017-03-24 11:41:47,376 DEBUG BasicDataSource [builtinApplication.JRTE_METADATA_add] Validating 1 'JRTE_METADATA's at path ''
        2017-03-24 11:41:47,376 DEBUG BasicDataSource [builtinApplication.JRTE_METADATA_add] Validating a 'JRTE_METADATA' at path ''
        2017-03-24 11:41:47,376 DEBUG BasicDataSource [builtinApplication.JRTE_METADATA_add] for field: DATASOURCE_IDadding automatically generated lengthRange validator for length:30
        2017-03-24 11:41:47,376 DEBUG BasicDataSource [builtinApplication.JRTE_METADATA_add] for field: DESCRIZIONEadding automatically generated lengthRange validator for length:255
        2017-03-24 11:41:47,376 DEBUG BasicDataSource [builtinApplication.JRTE_METADATA_add] for field: CREATORadding automatically generated lengthRange validator for length:255
        2017-03-24 11:41:47,376 DEBUG BasicDataSource [builtinApplication.JRTE_METADATA_add] for field: MODIFIERadding automatically generated lengthRange validator for length:255
        2017-03-24 11:41:47,376 DEBUG BasicDataSource [builtinApplication.JRTE_METADATA_add] for field: PLACEHOLDERadding automatically generated lengthRange validator for length:255
        2017-03-24 11:41:47,380 DEBUG SQLDataSource [builtinApplication.JRTE_METADATA_add] DataSource 9668 acquired SQLDriver instance 700644862 during initialization
        2017-03-24 11:41:47,380 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Created DataSource 9668 of type 'JRTE_METADATA' and assigned it to thread http-nio-8443-exec-20
        2017-03-24 11:41:47,380 DEBUG DSRequest [builtinApplication.JRTE_METADATA_add] Caching instance 9668 of DS 'JRTE_METADATA' from DSRequest.getDataSource()
        2017-03-24 11:41:47,380 DEBUG DSRequest [builtinApplication.JRTE_METADATA_add] Caching instance 9668 of DS JRTE_METADATA
        2017-03-24 11:41:47,380 DEBUG DeclarativeSecurity [builtinApplication.JRTE_METADATA_add] Processing security checks for DataSource null, field null
        2017-03-24 11:41:47,380 DEBUG DeclarativeSecurity [builtinApplication.JRTE_METADATA_add] Request is not a client request, ignoring security checks.
        2017-03-24 11:41:47,380 WARN  DataSourceDMI [builtinApplication.JRTE_METADATA_add] operationBinding for DataSource: JRTE_METADATA with operationType: fetch, operationId: fetchDefault does not have a <serverObject> in force and does not specify any operationBinding settings that could affect its behavior. This operation will almost certainly give the same result as a default operation, and so is almost certainly unnecessary
        2017-03-24 11:41:47,380 DEBUG AppBase [builtinApplication.JRTE_METADATA_add, builtinApplication.fetchDefault] No userTypes defined, allowing anyone access to all operations for this application
        2017-03-24 11:41:47,380 DEBUG AppBase [builtinApplication.JRTE_METADATA_add, builtinApplication.fetchDefault] No public zero-argument method named '_fetchDefault' found, performing generic datasource operation
        2017-03-24 11:41:47,380 INFO  SQLDataSource [builtinApplication.JRTE_METADATA_add, builtinApplication.fetchDefault] Performing fetch operation with
            outputs: [ID_REC, PLACEHOLDER]    criteria: {PLACEHOLDER:"{{today_ora}}"}    values: {PLACEHOLDER:"{{today_ora}}"}
        2017-03-24 11:41:47,380 INFO  SQLDataSource [builtinApplication.JRTE_METADATA_add, builtinApplication.fetchDefault] derived query: SELECT $defaultSelectClause FROM $defaultTableClause WHERE $defaultWhereClause
        2017-03-24 11:41:47,380 INFO  SQLDataSource [builtinApplication.JRTE_METADATA_add, builtinApplication.fetchDefault] 9668: Executing SQL query on 'dbJFrame': SELECT JRTE_METADATA.ID_REC, JRTE_METADATA.PLACEHOLDER FROM DBJFRAME.JRTE_METADATA WHERE (LOWER(JRTE_METADATA.PLACEHOLDER)='{{today_ora}}')
        2017-03-24 11:41:47,384 DEBUG PoolableSQLConnectionFactory [builtinApplication.JRTE_METADATA_add, builtinApplication.fetchDefault] makeObject() created an unpooled Connection '1494228984'
        2017-03-24 11:41:47,384 DEBUG SQLConnectionManager [builtinApplication.JRTE_METADATA_add, builtinApplication.fetchDefault] Borrowed connection '1494228984'
        2017-03-24 11:41:47,384 DEBUG SQLTransaction [builtinApplication.JRTE_METADATA_add, builtinApplication.fetchDefault] Started new dbJFrame transaction "1494228984"
        2017-03-24 11:41:47,384 DEBUG SQLDataSource [builtinApplication.JRTE_METADATA_add, builtinApplication.fetchDefault] Setting DSRequest as being part of a transaction
        2017-03-24 11:41:47,384 INFO  SQLDriver [builtinApplication.JRTE_METADATA_add, builtinApplication.fetchDefault] Executing SQL query on 'dbJFrame' using connection '1494228984': SELECT JRTE_METADATA.ID_REC, JRTE_METADATA.PLACEHOLDER FROM DBJFRAME.JRTE_METADATA WHERE (LOWER(JRTE_METADATA.PLACEHOLDER)='{{today_ora}}')
        2017-03-24 11:41:47,544 INFO  DSResponse [builtinApplication.JRTE_METADATA_add] DSResponse: List with 1 items
        2017-03-24 11:41:47,548 DEBUG DSRequest [builtinApplication.JRTE_METADATA_add] freeOnExecute is false for request of type fetch on DataSource JRTE_METADATA - not freeing resources!
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'sequence' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'text' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'text' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'text' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'text' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'text' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'text' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'text' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'text' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'text' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'text' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'text' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'creatorTimestamp' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'modifierTimestamp' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'creator' but null was returned
        2017-03-24 11:41:47,548 DEBUG PoolableDataSourceFactory [builtinApplication.JRTE_METADATA_add] Tried to create DataSource  of type 'modifier' but null was returned
        2017-03-24 11:41:47,548 DEBUG ValidationContext [builtinApplication.JRTE_METADATA_add] Adding validation errors at path '/JRTE_METADATA/PLACEHOLDER/PLACEHOLDER': {errorMessage=PlaceHolder già  presente per l'applicazione inserita}
        2017-03-24 11:41:47,548 DEBUG BasicDataSource [builtinApplication.JRTE_METADATA_add] for field: NOMEadding automatically generated lengthRange validator for length:55
        2017-03-24 11:41:47,548 DEBUG BasicDataSource [builtinApplication.JRTE_METADATA_add] for field: NOME_GRUPPOadding automatically generated lengthRange validator for length:55
        2017-03-24 11:41:47,548 DEBUG BasicDataSource [builtinApplication.JRTE_METADATA_add] for field: DS_FIELDadding automatically generated lengthRange validator for length:30
        2017-03-24 11:41:47,548 DEBUG BasicDataSource [builtinApplication.JRTE_METADATA_add] Done validating 1 'JRTE_METADATA's at path '': 172ms (avg 172)
        2017-03-24 11:41:47,548 DEBUG DataSource [builtinApplication.JRTE_METADATA_add] post-validation valueSet: [
            {
                NOME_GRUPPO:"sdf",
                NOME:"sdfsd",
                DESCRIZIONE:"dfds",
                DATASOURCE_ID:"sf",
                DS_FIELD:"sdf",
                PLACEHOLDER:"{{today_ora}}",
                DATE_CREATOR:new Date(1490352107376),
                DATE_MODIFIER:new Date(1490352107376),
                CREATOR:"claudio.bosticco@juventus.com",
                MODIFIER:"claudio.bosticco@juventus.com"
            }
        ]
        2017-03-24 11:41:47,548 INFO  Validation [builtinApplication.JRTE_METADATA_add] Validation error: [
            {
                PLACEHOLDER:{
                    errorMessage:"PlaceHolder già  presente per l'applicazione inserita"
                }
            }
        ]
        2017-03-24 11:41:47,552 DEBUG DSRequest About to free up resources for request of type add on DataSource JRTE_METADATA
        I must specify that the database is Oracle, don't know if the unique constraint behaves differently for other databases in respect to null values.
        Last edited by claudiobosticco; 24 Mar 2017, 03:31.

        Comment


          #5
          Have you tried submitting ID_APP as an explicit null? We wouldn't want to assume absence of a value is equivalent to null; that seems like a gotcha for typical cases of unique checks.

          Comment


            #6
            Thanks for the hint, setting a default of null (using startEditingNew) works.

            Comment


              #7
              Originally posted by Isomorphic View Post
              We think it's probably not correct to use the cacheSyncOperation - that could be there for a totally different purpose, including no-oping for performance reasons. But we agree that it would be useful to be able to specify an operationId on the validator, and we will add that, as a new feature on the 11.1 branch only. We will post back on this thread when that has been done.
              Hello, I've just found this thread as I recalled that you added the operationId for the validator, actually I thought it was also for applyWhen validators, but I see that we'd discussed it only for the isUnique validator.

              Actually I have a similar use case but with an applyWhen validator, wouldn't it be useful for this case also?

              Comment


                #8
                SmartClient Version: SNAPSHOT_v12.1d_2019-06-03/EVAL Deployment (expires 2019.08.02_07.20.48) Licensed to: Isomorphic Software (#ISC_EVAL_NIGHTLY)

                Actually my specific use case could arise because of a bug.

                In the automatic fetch generated for the applyWhen validator, there is explicitly listed a binary field (which normally isn't).

                My query has a groupClause, and I've got an error because the groupClause doesn't contain the binary field, and Oracle doesn't allow the grouping by a BLOB.

                So, is it normal that the binary field is listed in the SELECT clause of the query, or is it a bug?

                Comment


                  #9
                  Actually I see that the the fetches issued in DMI server side code (automatic fetch or not), contain the binary field.

                  Is it by design?

                  Comment


                    #10
                    just to double check, I've just tested the latest build:

                    SmartClient Version: SNAPSHOT_v12.1d_2019-06-14/EVAL Deployment (expires 2019.08.13_07.44.24) Licensed to: Isomorphic Software (#ISC_EVAL_NIGHTLY)

                    same behaviour.

                    Please note that the stratus skin has a 'red' as background color of the cell style, in this latest build.

                    Comment


                      #11
                      applyWhen is not a validator type but a validator attribute that applies across multiple types of validators. Could you clarify what situation you are talking about - an applyWhen applied to an isUnique validator? Or something else?

                      Comment


                        #12
                        My use case is a type="required" validator with an applyWhen attribute.
                        The default fetch has a custom groupClause, and it raises an error because the groupClause doesn't contain a binary field, which is indeed included in the Select columns when the fetch is executed from server side code, as in the automatic fetch triggered by the applyWhen.
                        So, I could workaround this behaviour if the operationId attribute were usable even with the type=required validator.

                        But also, I wonder if the fact that the binary field is listed in the Select colums for a server-initiated fetch is by design or a bug.

                        Comment


                          #13
                          applyWhen only does a fetch for the special edge case of applyWhen+required (explained in the linked docs for required). A special operationId for this situation seems like overkill.

                          Instead we would recommend that you switch your default fetch back to a more basic fetch that works for the various cases where the framework needs to do a basic fetch (various validators, for formItem.fetchMissingValues, cache sync, others). Then in the places where you need to do a special grouped fetch, use operationId to configure that.

                          This is likely to result in less instances of needing to set operationId overall.

                          Comment


                            #14
                            Hi Isomorphic,

                            while I agree which your "keep the basic fetch simple", for the reasons you mention in #13, this is sometimes hard to do, especially in existing applications. Here a operationId-attribute, like the one you introduced in #3 two years ago for isUnique really helps.

                            I now have the same problem as claudiobosticco, but for the hasRelatedRecord-validator (see here for the why). Can you also add support for the operationId-attribute to hasRelatedRecord-validator?

                            Thank you & Best regards
                            Blama

                            PS: W.r.t. to "keep the basic fetch simple" I do think that this would really help as notice somewhere in the Quick Start Guide or the OperationBinding or DSOperationType.FETCH docs. For me it is now "too late" without a huge refactoring.

                            Comment

                            Working...
                            X