I'm just starting out a new project, and am trying to impliment a ISaveOrUpdateEventListener to set the datecreated and dateupdated fields on my entities.
I've been trying to follow a simplified version of the solution found here: http://fabiomaulo.blogspot.com/2011/05/nhibernate-bizarre-audit.html
Here's my listener:
Namespace Repositories
Public Class UpdateAndInsertEventListener
Implements ISaveOrUpdateEventListener
Public Sub OnSaveOrUpdate([event] As NHibernate.Event.SaveOrUpdateEvent) Implements NHibernate.Event.ISaveOrUpdateEventListener.OnSaveOrUpdate
Dim entity = TryCast([event].Entity, IDateCreatedAndUpdated)
If entity IsNot Nothing Then
Dim dateUpdated = DateTime.Now
If entity.DateCreated Is Nothing Then
entity.DateCreated = dateUpdated
End If
entity.DateUpdated = dateUpdated
End If
End Sub
End Class
End Namespace
and here's my hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string"></property>
<property name="show_sql">true</property>
<event type="save-update">
<listener class="Project.Repositories.UpdateAndInsertEventListener, Project"/>
</event>
</session-factory>
</hibernate-configuration>
my problem is, it's never running the code in my listener, so it's trying to insert null into my db :( I tried putting break points in, but they are never hit.
I think i'm missing a step somewhere but i'm not sure where.
here's the stack trace from the failing test:
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) System.Data.SqlClient.SqlDataReader.ConsumeMetaData() System.Data.SqlClient.SqlDataReader.get_MetaData() System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader() NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd) NHibernate.Id.IdentityGenerator.InsertSelectDelegate.ExecuteAndExtract(IDbCommand insert, ISessionImplementor session) NHibernate.Id.Insert.AbstractReturningDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder) NHibernate.Id.Insert.AbstractReturningDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder) NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Boolean[] notNull, SqlCommandInfo sql, Object obj, ISessionImplementor session) NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Object obj, ISessionImplementor session) NHibernate.Action.EntityIdentityInsertAction.Execute() NHibernate.Engine.ActionQueue.Execute(IExecutable executable) NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) NHibernate.Event.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event) NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event) NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event) NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event) NHibernate.Impl.SessionImpl.Save(Object obj) Project.Repositories.UserRepository.Add(User user) in C:\Projects\Project\Project\Repositories\UserRepository.vb: line 10 Project.Tests.CRUDTest.CRUDTest() in C:\Projects\Project\Project.Tests\Repositories\UserRepository\CRUDTest.vb: line 50
Thanks for the help!
Edit: I've changed my helper to add the listener there. it seems to be working for the updates, but when i am creating new entities, it does't seem to be getting to the listener still. I've also removed the "register" sub from my
Imports NHibernate
Namespace Repositories
Public Class NhibernateHelper
Private Shared m_sessionFactory As ISessionFactory
Private Shared ReadOnly Property SessionFactory As ISessionFactory
Get
If m_sessionFactory Is Nothing Then
Dim config As New NHibernate.Cfg.Configuration
config.Configure("C:/Projects/Project/Project.Tests/hibernate.cfg.xml")
config.AddAssembly(GetType(Entities.User).Assembly)
config.EventListeners.SaveEventListeners = config.EventListeners.SaveEventListeners.Concat({New UpdateAndInsertEv开发者_JS百科entListener}).ToArray
config.EventListeners.SaveOrUpdateEventListeners = config.EventListeners.SaveOrUpdateEventListeners.Concat({New UpdateAndInsertEventListener}).ToArray
config.EventListeners.UpdateEventListeners = config.EventListeners.UpdateEventListeners.Concat({New UpdateAndInsertEventListener}).ToArray
m_sessionFactory = config.BuildSessionFactory
End If
Return m_sessionFactory
End Get
End Property
Public Shared Function OpenSession() As ISession
Return SessionFactory.OpenSession()
End Function
End Class
End Namespace
There is an issue with your registration code:
listeners.SaveEventListeners.Concat
This does not modify the SaveEventListeners collection, but instead returns a new collection. You need to set the collection.
精彩评论