I\'m trying to use NHibernate with an existing database. In the data-model there is columns in each table that contains the time and username of the last update made to a ro
Mookid's answer is correct although I would like to point out that if one is using S#arp Architecture, the NHib configuration should be set up as follows:
<hibernate-configuration>
<session-factory>
...
<event type="pre-update">
<listener class="MyListener, MyAssembly"/>
</event>
<event type="pre-insert">
<listener class="MyListener, MyAssembly"/>
</event>
</session-factory>
</hibernate-configuration>
The event elements go into the session-factory element.
You should register a listener to the pre insert and pre update events. You can do it through your configuration like so:
<hibernate-configuration>
...
<event type="pre-update">
<listener class="MyListener, MyAssembly"/>
</event>
<event type="pre-insert">
<listener class="MyListener, MyAssembly"/>
</event>
</hibernate-configuration>
and then implement a listener - something like this (might not be entirely accurate - written off my memory):
public class MyListener : IPreUpdateEventListener, IPreInsertEventListener
{
public bool OnPreUpdate(PreUpdateEvent evt)
{
if (evt.Entity is IHasLastModified)
UpdateLastModified(evt.State, evt.Persister.PropertyNames);
return false;
}
public bool OnPreInsert(PreInsertEvent evt)
{
if (evt.Entity is IHasLastModified)
UpdateLastModified(evt.State, evt.Persister.PropertyNames);
return false;
}
void UpdateLastModified(object[] state, string[] names)
{
var index = Array.FindIndex(names, n => n == "LastModified");
state[index] = DateTime.Now;
}
}
and do the same thing with the pre update event.
EDIT: This one takes care of insert as well as update and it seems to work.
Instead of using LIsteners, you can also use Interceptors: Audit changes using interceptor
Hey I just had to solve this on a project I am working on, here is my answer
public interface IDateModified
{
DateTime Created { get; set; }
DateTime Modified { get; set; }
}
public class CustomDefaultSaveOrUpdateEventListener
: DefaultSaveOrUpdateEventListener
{
protected override object EntityIsPersistent(SaveOrUpdateEvent evt)
{
var entity = evt.Entity as IDateModified;
if (entity != null)
{
entity.Modified = DateTime.Now;
}
return base.EntityIsPersistent(evt);
}
protected override object EntityIsTransient(SaveOrUpdateEvent evt)
{
var entity = evt.Entity as IDateModified;
if (entity != null)
{
entity.Created = entity.Modified = DateTime.Now;
}
return base.EntityIsTransient(evt);
}
}
Then in my configuration (I am using Fluent NHibernate to configure my unit tests in code)
configuration.EventListeners.SaveOrUpdateEventListeners
= new ISaveOrUpdateEventListener[]
{
new CustomDefaultSaveOrUpdateEventListener()
};
AWESOMENESSSSSSSS!