Announcement

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

    auditDSConstructor with spring bean

    Hi, reading the documentation regarding auditing, I understood that if I have a serverConstructor on my dataSource, it will be used by default as the auditDSConstructor.
    In my dataSource I have a serverConstructor using the Spring bean notation, but when I debug I do not see execution entering my implementation to perform the INSERT on the audit table.
    In fact, it does not enter even when explicitly specifying auditDSConstructor. Is there perhaps an issue with the Spring notation?

    It only works if I add the serverConstructor for my audit dataSource (by the way, I was wondering whether declaring it there would be equivalent).

    #2
    please note that I have an explicitly defined audit dataSource. In the decompiled code it seems that the logic to retrieve the serverConstructor is used only when the dataSource is automatically generated.

    Also, may I ask if there's some log category I can use to log audit-related messages?

    Comment


      #3
      In the meantime, I am running other tests after removing my audit dataSource, so that the framework creates it.
      However, I ran into a NullPointerException in AuditDSGenerator, where this piece of code fails because inside the variable f there is the requiredMessage attribute, but it is null:

      Code:
                                         for(Object key : f.keySet()) {
                                              if (!"valueMap".equals(key)) {
                                                  String val = f.get(key).toString();
      The field validator is defined as follows:

      Code:
      <validators>
                      <validator type="required">
                          <applyWhen fieldName="ID_NAZIONE_FK" operator="equals" value="118"/>
                      </validator>
                  </validators>
      a null check seems necessary

      Comment


        #4
        If serverConstructor isn't working, that almost certainly means something went wrong in the Spring lookup, and you should look at the server log to discover what that was.

        As doc'd, auditDSConstructor just works like serverConstructor for an automatically-generated audit DataSource.

        Whatever is going wrong is probably already being logged. However, this category would give you more information about audit DataSource construction:

        # In server.properties or log4j config
        log4j.category.com.isomorphic.datasource.AuditDSGenerator=DEBUG

        And these categories would give you a *lot* of information including more detail on serverConstructor:

        # Audit DS registration during DataSource init
        log4j.category.com.isomorphic.datasource.BasicDataSource=DEBUG

        # Audit record writing during operations
        log4j.category.com.isomorphic.datasource.DataSource=DEBUG

        But again, if Spring threw an exception when we tried to look up the bean you specified, that should already have been logged, unless you did something to squelch it.

        Comment


          #5
          As far as the second issue, which seems to be unrelated, you mentioned something about the requiredMessage attribute, but then showed XML that doesn't use that attribute - can you clarify?

          Comment


            #6
            Originally posted by Isomorphic View Post
            As far as the second issue, which seems to be unrelated, you mentioned something about the requiredMessage attribute, but then showed XML that doesn't use that attribute - can you clarify?
            yes, while debugging I see the requiredMessage key in the "f" variable (with null value)

            Comment


              #7
              Originally posted by claudiobosticco View Post
              In the meantime, I am running other tests after removing my audit dataSource, so that the framework creates it.
              However, I ran into a NullPointerException in AuditDSGenerator, where this piece of code fails because inside the variable f there is the requiredMessage attribute, but it is null:

              Code:
              for(Object key : f.keySet()) {
              if (!"valueMap".equals(key)) {
              String val = f.get(key).toString();
              The field validator is defined as follows:

              Code:
              <validators>
              <validator type="required">
              <applyWhen fieldName="ID_NAZIONE_FK" operator="equals" value="118"/>
              </validator>
              </validators>
              a null check seems necessary
              This is a screenshot of the debugger:

              Click image for larger version

Name:	2026-01-09 20.23.21.jpg
Views:	9
Size:	82.5 KB
ID:	276988

              and the LOCALITA field is defined like this:

              Code:
              <field name="LOCALITA" type="text" length="50">
                  <validators>
                      <validator type="required">
                          <applyWhen fieldName="ID_NAZIONE_FK" operator="notEqual" value="118"/>
                      </validator>
                  </validators>
              </field>

              Comment


                #8
                That looks like a real bug, we're on it. In the meantime obviously adding a requiredMessage is a workaround.

                Were you able to figure out your serverConstructor issues using the server log?

                Comment


                  #9
                  The audited DataSource JAS_SOCIETA has the following settings:
                  Code:
                              audit="true"
                              generateAuditDS="false"
                              auditDataSourceID="AUDIT_JAS_SOCIETA"
                              serverConstructor="spring:customBinaryFieldDataSource"
                              auditDSConstructor="spring:customBinaryFieldDataSource"
                  while the audit DataSource AUDIT_JAS_SOCIETA has:
                  Code:
                  auditedDataSourceID="JAS_SOCIETA"

                  The only logs related to AuditDSGenerator that I see are:

                  Code:
                  DEBUG AuditDSGenerator AUDIT_JAS_SOCIETA is an audit DataSource, processing
                  
                  DEBUG AuditDSGenerator getSpecialAuditFieldName() for auditTypeFieldName returns audit_operationType
                  DEBUG AuditDSGenerator getSpecialAuditFieldName() for auditUserFieldName returns audit_modifier
                  DEBUG AuditDSGenerator getSpecialAuditFieldName() for auditChangedFieldsFieldName returns audit_changedFields
                  DEBUG AuditDSGenerator getSpecialAuditFieldName() for auditTimeStampFieldName returns audit_changeTime
                  DEBUG AuditDSGenerator getSpecialAuditFieldName() for auditRevisionFieldName returns audit_revision
                  I have org.springframework at DEBUG, and there is no mention of my serverConstructor.

                  However, while debugging, execution enters my custom server DataSource only for JAS_SOCIETA, not for the audit DataSource.

                  The only way to have it enter my custom server DataSource for AUDIT_JAS_SOCIETA as well is to explicitly add the serverConstructor to AUDIT_JAS_SOCIETA:

                  Code:
                   serverConstructor="spring:customBinaryFieldDataSource"
                  If you have suggestions on how to further debug this, or on which parts of the audit DataSource initialization flow I should focus on, I would really appreciate it.

                  I am, of course, available to share additional logs or configuration details if that helps.

                  Comment


                    #10
                    We found the problem with the NPE with audit DataSource generation and fixed it for tomorrow's builds. Thanks for reporting that!

                    As far as the other problem - you seem to be using serverConstructor "spring:something" and it fails and there is no clear logging. This is surprising. Here's what we would expect:

                    Scenario 1: serverConstructor="spring:myBean" and Spring lookup throws an exception

                    DEBUG: Looking up Spring bean 'myBean' as implementer for DataSource X
                    WARN: Couldn't create DataSource X by looking up Spring bean 'myBean', creating
                    as a normal DataSource. The Spring lookup failed as follows: [stack trace]

                    Scenario 2: serverConstructor="spring:myBean" and Spring returns null or wrong type

                    DEBUG: Looking up Spring bean 'myBean' as implementer for DataSource X
                    WARN: Couldn't create DataSource X by looking up Spring bean 'myBean', creating
                    as a normal DataSource. The object returned by the Spring lookup was null

                    Are you saying you see neither of these logs?

                    If so - what happens if you call Spring directly to get this bean? If there's an exception in that case, can you share it - we want to understand why you aren't already seeing clear logging of a failure.

                    Comment


                      #11
                      Hi, however I would like to point out that the bean lookup specified via serverConstructor (on the audited DataSource) is working.

                      The lookup for the audit DataSource specified via auditDSConstructor (it points to the same Spring bean, so auditDSConstructor should be optional, shouldn’t it?) is the one that is not working.

                      I do not see any anomalies in the logs, and the only reference to the Spring bean I can find is the following during Tomcat startup:

                      Code:
                      2026-01-10T13:12:02,431 [ ] DEBUG ClassPathBeanDefinitionScanner Identified candidate component class: file [/Users/bosticco/iscSDK/tools/visualBuilder/wsmvn/Jat/target/Jat/WEB-INF/classes/com/juve/azure/storage/CustomBinaryFieldDataSource.class]

                      Comment


                        #12
                        Additionally, I am not sure whether this is relevant, but while debugging into BasicDataSource.fromConfig(), I can see that it correctly retrieves the Spring bean for the audited DataSource JAS_SOCIETA.

                        I also notice that when execution enters this method for the audit DataSource, the serverConstructor attribute is null, so no bean lookup is performed, and it loads the default SQLDataSource.

                        In this class, I do not see any usage of either auditedDataSourceID or auditDSConstructor.
                        So far, I have found these two attributes to be used only in the AuditDSGenerator class, which, however, does not seem to be involved in my case since the audit DataSource is already explicitly defined.

                        Is this information useful?

                        Comment


                          #13
                          Originally posted by Isomorphic View Post
                          We found the problem with the NPE with audit DataSource generation and fixed it for tomorrow's builds. Thanks for reporting that!
                          SmartClient Version: v13.1p_2026-01-10/AllModules Development Only (built 2026-01-10)

                          I see this is working now, thank you very much.

                          Comment


                            #14
                            Originally posted by claudiobosticco View Post
                            In this class, I do not see any usage of either auditedDataSourceID or auditDSConstructor.
                            So far, I have found these two attributes to be used only in the AuditDSGenerator class
                            Regarding the usage of auditedDataSourceID in AuditDSGenerator, it is actually not read there, but written into the generated DataSource.

                            However, concerning the auditedDataSourceID attribute itself, which is documented as required, based on the various tests I have run it seems that omitting it has no effect: no warnings, no errors, and no apparent change in behavior.

                            Is this expected?

                            Comment


                              #15
                              For auditDSConstructor, it is the serverConstructor "for the automatically generated audit DataSource", so it will not have an effect if you have hand-created the audit DataSource. So for a manually-created audit DataSource, you just use serverConstructor as usual - you don't have to do anything special (and you reported this was working for you, right?).

                              That's why you only see auditDSConstructor referenced in the AuditDSGenerator - that's as it should be, and as doc'd.

                              "auditedDataSourceId" (note the "ed" - audited) is a property we generate into an automatically-generated audit DataSource. We do doc that this is required if you manually create an audit DataSource, but the only place we actually use it is in some tools, so that's why you didn't notice any references to it outside of AuditDSGenerator. It's best to just go ahead and follow the docs here, as there many be other reliances on this required property in the future.

                              So, there's a bunch of confusing stuff above - can you just confirm - everything is working for you now, right?



                              Comment

                              Working...
                              X