views:

366

answers:

2

I have a NHibernate Interceptor that is set in the HibernateTemplate using Spring.Net (I'm using ASP.NET MVC, fwiw), which is used for Auditing. However, for some reason, while the OnLoad method is being triggered when I call genericDAO.Get(id), when I try to save something using genericDAO.SaveOrUpdate(object) neither the OnSave or OnFlushDirty Interceptor methods are called. Anyone know why this might be?

I've set breakpoints on the methods within VS debugger, so I'm pretty certain the Interceptor is set and that I'm not missing any method calls. Obviously, everything is being saved and retrieved correctly too.

public class AuditInterceptor
    : EmptyInterceptor
{

     public override bool OnLoad(object entity, object id, object[] state, string[] propertyNames, IType[] types)
    {
        // Implementation
        // Called when using genericDAO.Get(id)
    }

    public override bool OnSave(Object entity, Object id, Object[] state,
        String[] propertyNames, IType[] types)
    {
        // Implementation
        // NOT called when using genericDAO.SaveOrUpdate(entity)
    }

    public override bool OnFlushDirty(Object entity, Object id,
        Object[] currentState, Object[] previousState,
        String[] propertyNames, IType[] types)
    {
        // Implementation
    }
}
A: 

This is a cut-down (and anonymised) version of my objects.xml file:

  <object id="MyController" singleton="false" type="Project.Web.Controllers.MyController">
    <constructor-arg name="dashboardService" ref="DashboardService" />
  </object> 

<object id="DashboardService" type="Project.Business.Services.DashboardService, Project.Business">
    <constructor-arg name="dashboardDao" ref="DashboardDao" />
  </object>  

<object id="DashboardDao" type="Project.Data.Dao.DashboardDao, Project.Data">
    <property name="SessionFactory" ref="SessionFactory"/>
    <property name="HibernateTemplate" ref="myHibernateTemplate" />
  </object>

 <object id="myHibernateTemplate" type="Spring.Data.NHibernate.Generic.HibernateTemplate, Spring.Data.NHibernate20">
    <property name="SessionFactory" ref="SessionFactory"/>
    <property name="EntityInterceptor" ref="myAuditInterceptor"/>
    <property name="TemplateFlushMode" value="Auto" />
    <property name="CacheQueries" value="true" />
  </object>

  <object id="myAuditInterceptor" type="Project.Business.Audit.AuditInterceptor, Project.Business">
    <constructor-arg name="userService" ref="userService" />
    <constructor-arg name="auditService" ref="auditService" />
    <constructor-arg name="sessionFactory" ref="myAuditSessionFactory" />
  </object>

 <db:provider id="myDbProvider"
               provider="SqlServer-2.0"
               connectionString="Data Source=(local);Initial Catalog=myDB;Integrated Security=SSPI" />


  <object id="SessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate20">
    <property name="DbProvider" ref="myDbProvider"/>
    <property name="MappingAssemblies">
      <list>
        <value>Project.Data</value>
      </list>
    </property>
    <property name="HibernateProperties">
      <dictionary>
        <entry key="connection.provider"
               value="NHibernate.Connection.DriverConnectionProvider"/>
        <entry key="dialect"
               value="NHibernate.Dialect.MsSql2005Dialect"/>
        <entry key="connection.driver_class"
               value="NHibernate.Driver.SqlClientDriver"/>
      </dictionary>
    </property>
  </object>

  <object id="myAuditSessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate20">
    <property name="DbProvider" ref="myDbProvider"/>
    <property name="MappingAssemblies">
      <list>
        <value>Project.Data</value>
      </list>
    </property>
    <property name="HibernateProperties">
      <dictionary>
        <entry key="connection.provider"
               value="NHibernate.Connection.DriverConnectionProvider"/>
        <entry key="dialect"
               value="NHibernate.Dialect.MsSql2005Dialect"/>
        <entry key="connection.driver_class"
               value="NHibernate.Driver.SqlClientDriver"/>
      </dictionary>
    </property>
  </object>
LucyB
A: 

It seems that you do not use transactions. You should try using them as shown in the Spring Nhibernate sample (e.g.:) and activate logging to really see if the session gets flushed.

<!-- Hibernate Transaction Manager-->
<object id="hibernateTransactionManager" type="Spring.Data.NHibernate.HibernateTransactionManager , Spring.Data.NHibernate20">
<property name="DbProvider" ref="myDbProvider"/>
<property name="SessionFactory" ref="SessionFactory"/>
<property name="EntityInterceptor" ref="myAuditInterceptor"/>
</object>

Also you are declaring two session factories. It is not related I guess but is this intentional? Also this rather old thread for Java's spring might be helpful.

tobsen
Thanks, I'll have a play with the transaction manager. The two session factories are intentional to avoid problems when the interceptor writes back to the database.
LucyB