1
votes

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 UpdateAndInsertEventListener}).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
1

1 Answers

1
votes

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.