Hi, I am attempting to make use of IInterceptor in order to implement auditing. I'm having problems because when I call ICriteria.UniqueResult<T>(), which forces a flush to occur and therefore my interceptor to fire, the internal state of the entities that have changed doesn't seem to get updated. This means that if/when flush gets called again, my interceptor fires again and I get duplicate entries in my audit log - any thoughts???? It seems like a bug to me.
I presume that that changing the flush mode to "commit" is one way that this problem could be resolved, however, auditing has been bolted on at the end of a sizable project, so I would be reluctant to start changing the flush mode now, since I would be fearful of what else it might break.
Hibernate version: 1.2.0.GA
Name and version of the database you are using: SQLServer 2000
Please find a more detailed explanation of the scenario below:
In the OnFlushDirty method of the interceptor I loop through all of the names in the propertyNames array, I then compare corresponding values in the currentState array and the previousState array and write an entry to the log if there is a difference.
Now consider the following:
Code:
ISession session = NHibernateSessionManager.Instance.GetSession();
Contact contact = session.Get<Contact>(1); // Read contact "Dave"
contact.PreferredName = "Updated preferred name";
session.Flush(); // #### Flush 1 ####
contact.Forename = "Updated forename";
session.Flush(); // #### Flush 2 ####
session.SaveOrUpdateCopy(contact);
In this scenario everything happens as I would expect. When "flush 1" occurs the entries in previousState array and currentState array for the PreferredName field of contact have "Dave" and "Updated preferred name" respectively. There is a difference and therefore an entry is written to the audit log. When "flush 2" occurs the entries in previousState array and currentState array for the Forename field are different, and the entries for PreferredName both have the new value of "Updated preferred name"; this results in one extra audit log entry for the change to the Forename field.
In the scenario I am having a problem with, before "Flush 2" happens I am reading another record using an ICriteria object to build up a query and return the result of ICriteria.UniqueResult<T>(). When UniqueResult() fires it forces a flush which again results in a single audit record being written, however, when "Flush 2" occurs, the internal state doesn't seem to have been updated when UniqueResult() was called. This means that my interceptor fires again, and when the currentState and previousState of the Forename field are compared they are different rather than both having the value "Updated Forename" I therefore end up with two entries in my audit log for the change to the forename field.