Implementing NHibernate Interceptors

One of the areas where NHibernate really shines is it’s high extensibility features. The NHibernate API provides a massive amount of interfaces that can be implemented for your own custom extension pleasure.

For me this is a nice change as opposed to the many sealed API’s put out by the Redmond collective (WCF being the exception, the Entity Framework confirming the rule).

Anyhow, with great power comes great responsibility. Today I encountered a rather difficult problem with NHibernate that could have been easily prevented by reading the documentation (note to self: use the CTRL-Q shortcut of Resharper more often).

We have implemented an interceptor for automatically configuring audit information as described by this great post from Ray Houston.

public class AuditInformationInterceptor : EmptyInterceptor { Boolean OnSave(Object entity, Object id, Object[] state, String[] propertyNames, IType[] types) { // Implementation } Boolean OnFlushDirty(Object entity, Object id, Object[] currentState, Object[] previousState, String[] propertyNames, IType[] types) { // Implementation } }

The mistake we made is that we manipulated the audit information of the entity directly in the OnSave and OnFlushDirty methods. This only became apparent when saving an aggregate root with his child entities. Everything worked fine until we wanted to persist one of the child entities that should have been a piece of cake but turned out to be the messenger of trouble. NHibernate refused to perform an INSERT statement, but instead threw an UPDATE statement at us.

After some debugging we found out that the audit information should have been manipulated through the state and currentState arguments of the OnSave and OnFlushDirty methods respectively.

The documentation of the OnSave method clearly states:

The interceptor may modify the state, which will be used for the SQL INSERT

and propagated to the persistent object

Lesson relearned.

I’m off, reading some docs. Until next time.

Published by

Jan Van Ryswyck

Hi, thank you for visiting my blog and reading all the crap that I'm posting here. I'm a senior software engineer at SD WORX. Developing software is one of my greatest passions in life, and I enjoy doing it every single day. I've got three kids (Len, Lisa & Laura) who constantly remind me that there is more in life than just programming all day. They are the greatest kids in the whole world. And last but not least, there's my girlfriend who is my inspiration in life. You can always contact me at jan_dot_van_dot_ryswyck at gmail.com

4 thoughts on “Implementing NHibernate Interceptors”

  1. I had exactly the same situation recently. I am using ActiveRecord and I was trying to use BeforeSave / OnFlushDirty overrides to set some data in my objects, e.g. creation date, but the changes were not saved to DB. I found your post and after reading it I was like “aah, that’s why!” – I was changing the object, and as you wrote, I should rather change the state/currentState collections. Many thanks!

Comments are closed.