mk77
02-27-2007, 04:45 PM
I would like to implement audit logging for my system that would automatically record who and when created/updated a record in the database. I created the following Hibernate Interceptor to update object properties prior to the object being saved to the database (partial code):
using System;
using System.Collections;
using NHibernate;
using NHibernate.Type;
using Common.Logging;
namespace Pohs.DAL
{
class AuditInterceptor : IInterceptor
{
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase. GetCurrentMethod().DeclaringType);
public bool OnFlushDirty(object entity, object id, object[] currentState, object[] previousState,
string[] propertyNames, IType[] types)
{
log.Debug("FLUSH DIRTY");
for ( int i=0; i < propertyNames.Length; i++ )
{
if ("UpdatedDateTime" == propertyNames[i])
{
currentState[i] = DateTime.Now;
return true;
}
}
return false;
}
public bool OnSave(object entity, object id, object[] state, string[] propertyNames, IType[] types)
{
log.Debug("SAVE");
for ( int i=0; i<propertyNames.Length; i++ )
{
if ("CreatedDateTime" == propertyNames[i])
{
state[i] = DateTime.Now;
return true;
}
}
return false;
}
.........
.........
}
}
And I registered it with the HibernateTransactionManager using the entityInterceptor property like:
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net" xmlns:d="http://www.springframework.net/database">
<!-- Database Connection Provider -->
<d:dbProvider id="databaseProvider"
provider="System.Data.SqlClient"
connectionString="Server=Server;Database=Database;Trusted_Connection =Yes;"/>
<!-- Hibernate session factory -->
<object id="hibernateSessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate12">
<property name="DbProvider" ref="databaseProvider"/>
<property name="MappingAssemblies">
<list>
<value>Pohs.DAL</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<entry key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect"/>
<entry key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
<entry key="hibernate.connection.isolation" value="ReadCommitted" />
<entry key="hibernate.default_schema" value="Pohs.dbo"/>
</dictionary>
</property>
</object>
<!-- Audit Logging Interceptor -->
<object id="auditInterceptor"
type="Pohs.DAL.AuditInterceptor, Pohs.DAL">
</object>
<!-- Hibernate transaction manager -->
<object id="hibernateTransactionManager" type="Spring.Data.NHibernate.HibernateTransactionManager , Spring.Data.NHibernate12">
<property name="DbProvider" ref="databaseProvider"/>
<property name="sessionFactory" ref="hibernateSessionFactory"/>
<property name="entityInterceptor" ref="auditInterceptor"/>
</object>
<!-- Configure Spring AOP autoproxy support -->
<object id="autoProxy"
type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoP roxyCreator, Spring.Aop">
</object>
<object id="transactionAttributeSource"
type="Spring.Transaction.Interceptor.AttributesTransacti onAttributeSource, Spring.Data">
</object>
<!-- Transaction Interceptor based on attribute [Transaction()] -->
<object id="transactionInterceptor" type="Spring.Transaction.Interceptor.TransactionIntercep tor, Spring.Data">
<property name="TransactionManager" ref="hibernateTransactionManager"/>
<property name="TransactionAttributeSource" ref="transactionAttributeSource"/>
</object>
<object id="transactionAdvisor"
type="Spring.Transaction.Interceptor.TransactionAttribut eSourceAdvisor, Spring.Data"
autowire="constructor">
</object>
</objects>
However, I can't get the Interceptor to execute. Am I doing something worng?
Thanks,
Max
using System;
using System.Collections;
using NHibernate;
using NHibernate.Type;
using Common.Logging;
namespace Pohs.DAL
{
class AuditInterceptor : IInterceptor
{
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase. GetCurrentMethod().DeclaringType);
public bool OnFlushDirty(object entity, object id, object[] currentState, object[] previousState,
string[] propertyNames, IType[] types)
{
log.Debug("FLUSH DIRTY");
for ( int i=0; i < propertyNames.Length; i++ )
{
if ("UpdatedDateTime" == propertyNames[i])
{
currentState[i] = DateTime.Now;
return true;
}
}
return false;
}
public bool OnSave(object entity, object id, object[] state, string[] propertyNames, IType[] types)
{
log.Debug("SAVE");
for ( int i=0; i<propertyNames.Length; i++ )
{
if ("CreatedDateTime" == propertyNames[i])
{
state[i] = DateTime.Now;
return true;
}
}
return false;
}
.........
.........
}
}
And I registered it with the HibernateTransactionManager using the entityInterceptor property like:
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net" xmlns:d="http://www.springframework.net/database">
<!-- Database Connection Provider -->
<d:dbProvider id="databaseProvider"
provider="System.Data.SqlClient"
connectionString="Server=Server;Database=Database;Trusted_Connection =Yes;"/>
<!-- Hibernate session factory -->
<object id="hibernateSessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate12">
<property name="DbProvider" ref="databaseProvider"/>
<property name="MappingAssemblies">
<list>
<value>Pohs.DAL</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<entry key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect"/>
<entry key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
<entry key="hibernate.connection.isolation" value="ReadCommitted" />
<entry key="hibernate.default_schema" value="Pohs.dbo"/>
</dictionary>
</property>
</object>
<!-- Audit Logging Interceptor -->
<object id="auditInterceptor"
type="Pohs.DAL.AuditInterceptor, Pohs.DAL">
</object>
<!-- Hibernate transaction manager -->
<object id="hibernateTransactionManager" type="Spring.Data.NHibernate.HibernateTransactionManager , Spring.Data.NHibernate12">
<property name="DbProvider" ref="databaseProvider"/>
<property name="sessionFactory" ref="hibernateSessionFactory"/>
<property name="entityInterceptor" ref="auditInterceptor"/>
</object>
<!-- Configure Spring AOP autoproxy support -->
<object id="autoProxy"
type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoP roxyCreator, Spring.Aop">
</object>
<object id="transactionAttributeSource"
type="Spring.Transaction.Interceptor.AttributesTransacti onAttributeSource, Spring.Data">
</object>
<!-- Transaction Interceptor based on attribute [Transaction()] -->
<object id="transactionInterceptor" type="Spring.Transaction.Interceptor.TransactionIntercep tor, Spring.Data">
<property name="TransactionManager" ref="hibernateTransactionManager"/>
<property name="TransactionAttributeSource" ref="transactionAttributeSource"/>
</object>
<object id="transactionAdvisor"
type="Spring.Transaction.Interceptor.TransactionAttribut eSourceAdvisor, Spring.Data"
autowire="constructor">
</object>
</objects>
However, I can't get the Interceptor to execute. Am I doing something worng?
Thanks,
Max