Re: Identifying changed fields

From: Mike Kienenberger (mkienen..laska.net)
Date: Thu Oct 14 2004 - 21:10:34 EDT

  • Next message: Twan Kogels: "Re: DATETIME type in mysql?"

    Steve Steinitz <steinit..atatactics.com.au> wrote:
    > My apologies if this is an FAQ -- I couldn't find anything in my
    > quick searches in the docs, list archives, api and google.
    >
    > I need to make an audit trail of changes to an object. Is there
    > support in the API for identifying, at commitChanges time, properties
    > which differ from the database? Also, would I do this comparison at
    > validation time?
    >
    > DataRow.createDiff is tantalizing but I can't quite see how to use it
    > for this purpose.

    I think it's been talked about briefly on the mailing lists, but I think
    it'd be hard to locate.

    I can tell you how I perform this task, which some might call the "hard"
    way. It does not depend on the framework being able to identify changes.

    My class generator template files creates "setAndLogX" methods and marks the
    original "setX" methods private.
    Each setAndLogX method also creates a Log record detailing the changes to
    that particular object.

    The advantage is that this is almost transparent to the application once
    this is set up (or could be -- for my own use, I have to also log some
    authentication information with each record, so I pass a couple more
    parameters to each method.) If the change commits, so does the log. If
    the change fails for any reason and gets rolled back, so does the change
    log.

    Below is a simplified snippet of what code gets generated. There's a lot of
    hardcoded references created by the class-generator. You could be more
    abstract at a performance cost, but I don't think you gain anything by it
    since the class generator can automatically regenerate the code if the
    ObjectEntity changes.

    Note that you also probably need to log "delete"s and "insert"s (which I do
    using the same strategy).

        public void setAmountType(String aValue)
        {
            writeProperty("amountType", aValue);
        }

        public void setAndLogAmountType(String aValue)
        {
            DataContext aDataContext = this.getDataContext();
            ChangeLog aChangeLogObject =
    (ChangeLog)aDataContext.createAndRegisterNewObject("ChangeLog");
            
            aChangeLogObject.setModificationDate(new Date());
            aChangeLogObject.setTableName("ScheduledPayment");
            aChangeLogObject.setFieldName("amountType");

            if (null == aValue)
            {
                aChangeLogObject.setNewValue(null);
            }
            else
            {
                String newValueString = aValue.toString();
                if (255 < newValueString.length()) newValueString =
    newValueString.substring(0, 255);

                aChangeLogObject.setNewValue(newValueString);
            }
            
            if (null == this.getAmountType())
            {
                aChangeLogObject.setOldValue(null);
            }
            else
            {
                String oldValueString = this.getAmountType().toString();
                if (255 < oldValueString.length()) oldValueString =
    oldValueString.substring(0, 255);

                aChangeLogObject.setOldValue(oldValueString);
            }

            
    aChangeLogObject.setForeignScheduledPaymentObject((ScheduledPayment)this);
            this.setAmountType(aValue);
        }

    > ps. let me take this opportunity to acknowledge Andrus' tireless,
    > patient and competant work in keeping this list an excellent
    > source of information -- I believe I would speak for everyone

    Yeah, we all pretty much take him for granted :)



    This archive was generated by hypermail 2.0.0 : Thu Oct 14 2004 - 21:09:36 EDT