In this post I am talking about auditing for the business, not the technical infrastructure. As an example story, users will want to see certain fields highlighted on a grid if that field has changed in the last week, and the info about the change (who, when, what) should be a tooltip for the cell.
Database trigger
- See Jon Galloway’s post on Auditing with SQL Server
- To generate an audit trigger in oracle you can do something similar.
NH Interceptor (per NH in action and the NH docs)
NH Listener (per the Hibernate docs)
Domain model
Because auditing is a simple application of interceptors there is a lot of guidance online about that approach, and using an interceptor was my first attempt at auditing.
But since the concept of an audit entry is important to the application (and the users!), it makes sense to promote this concept to a domain object. Reporting is simple and the behavior is easier to manage. Create a class called AuditEntry (with supporting mapping file) and hang collections of AuditEntry from the entity. Manage this collection in regular behavior:
public virtual void ChangeStatus(Employee employee, DateTime time, OrderStatus status) { if(this.Status != status) { AuditEntry entry = new AuditEntry(employee, time, this.Status, status); _auditEntries.Add(entry); } Status = status; }
After having gone down the database trigger path and the interceptor path and encountering friction I now recommend the domain model approach.
Pingback: Dew Drop - July 12, 2008 | Alvin Ashcraft's Morning Dew
Pingback: So you want to learn NHibernate? - Part 1 of 1, The Links « HSI Developer Blog
Pingback: So you want to learn NHibernate? (or, NHibernate Hyperlink Acupuncture) | The Freak Parade
How did you handle audits of deletions? When the AuditEntry list hangs off your entity, then you would need to add the entry to the session then delete the entity in order to get them to persist. I thought to perhaps have the Delete method on the repository know to do those actions, except what then generates the entry?