-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Object Logging Method (Need suggestions!!)
PostPosted: Sat Mar 29, 2008 5:32 pm 
Newbie

Joined: Tue Jan 15, 2008 4:27 pm
Posts: 5
Hello everyone!

I want to log property changes on a few of my objects...

I have the following object graph:

Customer
BillingAccount
Device
DeviceHistory

Customers have a set of BillingAccounts
BillingAccounts have a set of Devices
Device has a set of DeviceHistories

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="OmegaWeb.domain.Customer, OmegaWeb" table="customer" optimistic-lock="version">

    <id name="Id" column="CustomerId" type="Int32">
      <generator class="native" />
    </id>
    <version name="Version" type="Int32" />
    <property name="CustomerName" />
    <property name="Notes" />
    <property name="Created" />
    <many-to-one name="CreatedBy" cascade="none" class="OmegaWeb.domain.AuthUser, OmegaWeb" lazy="false">
      <column name="CreatedBy" />
    </many-to-one>
    <property name="LastModified" />
    <many-to-one name="LastModifiedBy" cascade="none" class="OmegaWeb.domain.AuthUser, OmegaWeb" lazy="false">
      <column name="LastModifiedBy" />
    </many-to-one>
    <property name="Deactivated" />
    <many-to-one name="DeactivatedBy" cascade="none" class="OmegaWeb.domain.AuthUser, OmegaWeb" lazy="false">
      <column name="DeactivatedBy" />
    </many-to-one>
    <set name="BillingAccountSet" table="billingaccount" cascade="all-delete-orphan" inverse="true" lazy="true">
      <key>
        <column name="CustomerId" />
      </key>
      <one-to-many class="OmegaWeb.domain.BillingAccount, OmegaWeb" />
    </set>
    <set name="DeviceGroupSet" table="devicegroup" cascade="all-delete-orphan" inverse="true" lazy="false">
      <key>
        <column name="CustomerId" />
      </key>
      <one-to-many class="OmegaWeb.domain.DeviceGroup, OmegaWeb" />
    </set>
    <set name="CustomerAdminUserSet" table="CustomerAdminUser" cascade="all-delete-orphan" inverse="true" lazy="true">
      <key>
        <column name="CustomerId" />
      </key>
      <one-to-many class="OmegaWeb.domain.CustomerAdminUser, OmegaWeb" />
    </set>
    <set name="AlertRecipientSet" table="AlertRecipient" cascade="delete-orphan" inverse="true" lazy="true">
      <key>
        <column name="CustomerId" />
      </key>
      <one-to-many class="OmegaWeb.domain.AlertRecipient, OmegaWeb" />
    </set>
  </class>
</hibernate-mapping>


Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="OmegaWeb.domain.BillingAccount, OmegaWeb" table="billingaccount" optimistic-lock="version">

    <id name="Id" column="BillingAccountId">
      <generator class="native" />
    </id>
    <version name="Version" type="Int32" />
    <many-to-one name="Customer" cascade="all" class="OmegaWeb.domain.Customer, OmegaWeb" lazy="false">
      <column name="CustomerId" />
    </many-to-one>
    <many-to-one name="CreatedBy" cascade="none" class="OmegaWeb.domain.AuthUser, OmegaWeb" lazy="false">
      <column name="CreatedBy" />
    </many-to-one>
    <property name="BillingAccountNumber" />
    <property name="Notes" />
    <property name="Created" />
    <property name="LastModified" />
    <many-to-one name="LastModifiedBy" cascade="none" class="OmegaWeb.domain.AuthUser, OmegaWeb" lazy="false">
      <column name="LastModifiedBy" />
    </many-to-one>
    <property name="Deactivated" />
    <many-to-one name="DeactivatedBy" cascade="none" class="OmegaWeb.domain.AuthUser, OmegaWeb" lazy="false">
      <column name="DeactivatedBy" />
    </many-to-one>
    <set name="DeviceSet" table="device" cascade="all-delete-orphan" inverse="true" lazy="true">
      <key>
        <column name="BillingAccountId" />
      </key>
      <one-to-many class="OmegaWeb.domain.Device, OmegaWeb" />
    </set>
   </class>
</hibernate-mapping>


Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="OmegaWeb.domain.Device, OmegaWeb" table="device" optimistic-lock="version">

    <id name="Id" column="DeviceId" type="Int32">
      <generator class="native" />
    </id>
    <version name="Version" type="Int32" />
    <many-to-one name="BillingAccount" cascade="all" class="OmegaWeb.domain.BillingAccount, OmegaWeb" lazy="false">
      <column name="BillingAccountId" />
    </many-to-one>
    <property name="Password" />
    <property name="MaxAllowedUsage" />
    <property name="Notes" />
    <property name="Created" />
    <many-to-one name="CreatedBy" cascade="none" class="OmegaWeb.domain.AuthUser, OmegaWeb" lazy="false">
      <column name="CreatedBy" />
    </many-to-one>
    <property name="LastModified" />
    <many-to-one name="LastModifiedBy" cascade="none" class="OmegaWeb.domain.AuthUser, OmegaWeb" lazy="false">
      <column name="LastModifiedBy" />
    </many-to-one>
    <property name="Deactivated" />
    <many-to-one name="DeactivatedBy" cascade="none" class="OmegaWeb.domain.AuthUser, OmegaWeb" lazy="false">
      <column name="DeactivatedBy" />
    </many-to-one>
    <one-to-one name="LastSession" class="OmegaWeb.domain.LastSession, OmegaWeb" constrained="false" />
    <set name="DeviceHistorySet" table="devicehistory" cascade="all-delete-orphan" inverse="true" lazy="false">
      <key>
        <column name="DeviceId" />
      </key>
      <one-to-many class="OmegaWeb.domain.DeviceHistory, OmegaWeb" />
    </set>
    <set name="SessionSet" table="session" cascade="save-update" lazy="true">
      <key column="DeviceId" />
      <one-to-many class="OmegaWeb.domain.Session, OmegaWeb" />
    </set>
    <set name="BillingSet" table="billing" cascade="all-delete-orphan" inverse="true" lazy="true">
      <key>
        <column name="DeviceId" />
      </key>
      <one-to-many class="OmegaWeb.domain.Billing, OmegaWeb" />
    </set>
    <set name="DeviceGroupSet" table="devicegroupdevice" cascade="save-update" lazy="true">
      <key column="DeviceId" />
      <many-to-many class="OmegaWeb.domain.DeviceGroup, OmegaWeb" column="DeviceGroupId" />
    </set>

  </class>
</hibernate-mapping>


I've implemented the IInterceptor interface as follows:
Code:
        public bool OnFlushDirty(object entity, object id, object[] state, object[] previousState, string[] propertyNames, IType[] types)
        {
            bool modified = false;
            if (entity is Domain)
            {
                AuthUser authUser = (AuthUser)HttpContext.Current.Session[AuthUser.SESSION_KEY];
                if (authUser == null)
                {
                    throw new Exception("Security Circumvention - AuthUser cannot be null in Audit Interceptor");
                }
                Hashtable indexes = GetAuditPropertyIndexes(propertyNames);
                int index;
                index = (int)indexes["lastmodified"];
                state[index] = DateTime.Now;
                index = (int)indexes["lastmodifiedby"];
                state[index] = authUser;
                modified = true;
            }
            else
            {
                modified = false;
            }

            //Handle logging
            Type type = entity.GetType();
            foreach (Attribute attr in type.GetCustomAttributes(true))
            {
                LogPropertyChanges logger = attr as LogPropertyChanges;
                if (logger != null)
                {
                    AuthUser authUser = (AuthUser)HttpContext.Current.Session[AuthUser.SESSION_KEY];
                    string HibernateSessionId = HttpContext.Current.Items["HibernateSessionId"] as string;
                    if (authUser == null || HibernateSessionId == null)
                    {
                        throw new Exception("Security Circumvention - Neither AuthUser nor SaveSessionId cannot be null in Logging Interceptor");
                    }
                    string[] PropertiesToLog = logger.Attributes;
                    Hashtable indexes = GetLogPropertyIndexes(PropertiesToLog, propertyNames);

                    string typeName = type.Name;
                    ChangeSet changeSet = new ChangeSet();
                    changeSet.ChangeValueSet = new HashedSet<ChangeValue>();
                    changeSet.AuthUser = authUser;
                    changeSet.ChangeDate = DateTime.Now;
                    changeSet.HibernateSessionId = HibernateSessionId;
                    changeSet.ModifiedId = int.Parse(id.ToString());
                    changeSet.ModifiedTable = typeName;

                    DAOGeneric<ChangeSet> daoChangeSet = new DAOGeneric<ChangeSet>();
                    foreach (DictionaryEntry entry in indexes)
                    {
                        ChangeValue changeValue = new ChangeValue();
                        changeValue.ColumnName = entry.Key.ToString();
                        object oldValue = previousState[(int)entry.Value];
                        object newValue = state[(int)entry.Value];
                        if (newValue != oldValue)
                        {
                            changeValue.OldValue = oldValue != null ? oldValue.ToString() : null;
                            changeValue.NewValue = newValue != null ? newValue.ToString() : null;
                            changeValue.ChangeSet = changeSet;
                            changeSet.ChangeValueSet.Add(changeValue);
                        }
                    }
                    daoChangeSet.SaveChangeSet(changeSet);
                }
            }
            return modified;
        }


I also have two logging objects, one called ChangeSet, the other ChangeValue

ChangeSet has a set of ChangeValues

Lets say I modify a DeviceHistory record, then call Save on Device, I get some duplication.. my database looks something like:

1997 2008-03-29 17:27:55.000 Device 5924 84 5ce4b2bd-2772-47bc-ae86-6eab4fa5b478
1998 2008-03-29 17:27:55.000 DeviceHistory 5924 84 5ce4b2bd-2772-47bc-ae86-6eab4fa5b478
1999 2008-03-29 17:27:55.000 Device 5924 84 5ce4b2bd-2772-47bc-ae86-6eab4fa5b478
2000 2008-03-29 17:27:55.000 DeviceHistory 5924 84 5ce4b2bd-2772-47bc-ae86-6eab4fa5b478



42 1997 MaxAllowedUsage 500000 564898000
43 1997 Notes NULL blahksdlfjkl
44 1998 Deactivated NULL 3/29/2008 5:27:55 PM
45 1999 MaxAllowedUsage 500000 564898000
46 1999 Notes NULL blahksdlfjkl
47 2000 Deactivated NULL 3/29/2008 5:27:55 PM
48 2000 DeactivatedBy NULL OmegaWeb.domain.AuthUser



I know this is a lot.. but any suggestions on how to do this? Am I going down the wrong path?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 29, 2008 11:07 pm 
Newbie

Joined: Tue Jan 15, 2008 4:27 pm
Posts: 5
It actually had nothing to do with this code.. The session was being flushed twice.. fixed.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.