C# – How to configure NHIbernate event listeners for Update and Save

cnhibernate

Following on from my previous question How to implement LastUpdate in NHibernate Entities?.

I have two columns on my audited tables in my database:

  1. created datetime default getdate() not null (the creation date of this row)

  2. lastUpdate datetime null (the datetime this row was last updated)

I want to create a listener for updates only in NHibernate, because the database engine takes care of new records with the default constraint. I tried to create a Custom listener with this code:

public class CustomUpdateEventListener : DefaultSaveOrUpdateEventListener
{
    protected override object PerformSaveOrUpdate(SaveOrUpdateEvent evt)
    {
        var entity = evt.Entity as IAuditableEntity;
        if (entity != null)
        {
            ProcessEntityBeforeUpdate(entity);
        }
        return base.PerformSaveOrUpdate(evt);
    }

    internal virtual void ProcessEntityBeforeUpdate(IAuditableEntity entity)
    {
        entity.UpdateDate = DateTime.Now;
    }
}

and it works great for updates, but it also gets run for Save events (when I add new rows to the database). I don't want it to fire for new rows. I tried to change the code to listen to Update events only but I can't work it out.

I tried to change the class to inherit from DefaultUpdateEventListener but there's no UpdateEvent (only SaveOrUpdate events or PreUpdate or PostUpdate)

I'm wondering if I should use the PreUpdate event and making my listener inherit from DefaultUpdateEventListener but then I'm not sure which method I need to override. There is no Update method to override.

Best Answer

You could make your class implement the IPreUpdateEventListener interface (and its OnPreUpdate method). Then add your class to the session event listerners through the config:

NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
cfg.EventListeners.PreUpdateEventListeners = 
    new IPreUpdateEventListener[] {new YourEventListener()};
sessionFactory = cfg.BuildSessionFactory();