NHibernate - how to check all areas of an entity?

I use NHibernate and am looking for a solution that will allow me to check for changes in all fields in the entity. I want to be able to create a history table for each object, that is, Users β†’ UsersHistory, which will have the same structure as the Users table, and additional fields, such as the type of operation (update, delete), userid of the user who made the change, etc. Do not want to define such a class for each object. I am looking for something like History<T> (i.e. History<User> ), because these records do not belong to my domain and will only be used to prepare a list of changes made to the object. I also think that it would be better to create inserts into these tables in the code, rather than creating sql triggers. Basically, I just need to create a copy of the record in the history table when updating or deleting, and I want the insert to be generated by NHibernate. I will also need to read the entries from the history tables - since I said that these tables will consist of entity fields and some common history fields.

I can not find a guide to create such a solution. All I can find is to add UserModified, UpdateTimestamp, etc., if I already have such fields in essence. However, I need a complete history of the entity, not just the information that last changed the record.

Thanks in advance for your help.

+7
source share
4 answers

NHibernate has a cool, open audit trail called nhibernate.envers https://bitbucket.org/RogerKratz/nhibernate.envers , so you don't have to reinvent the wheel.

It integrates transparently into NHibernate, no changes to your domain model or mappings.

It is as simple as adding a link and a call:

 var enversConf = new FluentConfiguration(); enversConf.Audit<User>(); nhConf.IntegrateWithEnvers(enversConf); 

whereas nhConf is your NHibernate configuration object.

For each change to your object, a new revision is created, you can ask Envers to get a version by calling:

 var reader = AuditReaderFactory.Get(session); var userInRevOne = reader.Find<User>(user.Id, 1); 

or list all changes, etc. The revision data itself can be enriched with the username, user ID, timestamp, etc. (whatever you think).

EDIT: And it is available on NuGet: http://nuget.org/packages/NHibernate.Envers

+14
source

I think the best solution is to listen to the listeners:

http://darrell.mozingo.net/2009/08/31/auditing-with-nhibernate-listeners/

I wrote something similar above (modified after discovering this blog), except that I save the result in XML.

eg:

 public void OnPostUpdate(PostUpdateEvent updateEvent) { if (updateEvent.Entity is AuditItem) return; var dirtyFieldIndexes = updateEvent.Persister.FindDirty(updateEvent.State, updateEvent.OldState, updateEvent.Entity, updateEvent.Session); var data = new XElement("AuditedData"); foreach (var dirtyFieldIndex in dirtyFieldIndexes) { var oldValue = GetStringValueFromStateArray(updateEvent.OldState, dirtyFieldIndex); var newValue = GetStringValueFromStateArray(updateEvent.State, dirtyFieldIndex); if (oldValue == newValue) { continue; } data.Add(new XElement("Item", new XAttribute("Property", updateEvent.Persister.PropertyNames[dirtyFieldIndex]), new XElement("OldValue", oldValue), new XElement("NewValue", newValue) )); } AuditService.Record(data, updateEvent.Entity, AuditType.Update); } 

The audit service simply creates additional additional data, such as the IP address, User (if any), whether it was an update of the system or service, or was performed through a website or user, etc.

Then in my DB I Store XML as:

 <AuditedData> <Item Property="Awesomeness"> <OldValue>above average</OldValue> <NewValue>godly</NewValue> </Item> <Item Property="Name"> <OldValue>Phill</OldValue> <NewValue>Phillip</NewValue> </Item> </AuditedData> 

I also have Insert / Delete listeners.

+4
source

What you are looking for are event listeners (unfortunately, I cannot link to the relevant documents because the nhforge.org wiki is testing NRE ...).

Check Integrated NHibernate Audit

0
source

Here is a complete example of how to do this: http://www.shawnduggan.com/?p=89 .

Also discussed in this article: nhibernate Audit Log

0
source

All Articles