NHibernate IPreUpdateEventListener不会插入第二个表

时间:2014-01-10 08:48:21

标签: session nhibernate fluent-nhibernate audit-logging ipreupdateeventlistener

我正在构建一些简单的审计日志记录功能。我有一个中等规模的实体模型(大约50个实体),我想在大约5或6上实现审计日志记录。最后我想让这个工作在Inserts&删除也是如此,但现在我只关注更新。

问题是,当我从EventListener中将session.Save(或SaveOrUpdate)传递给我的auditLog表时,原始对象会被正确保留(更新),但我的AuditLog对象永远不会被插入。

我认为PrePost事件监听器在NHibernate保存生命周期中被调用到会话仍然是一个问题。

//in my ISessionFactory Build method

nHibernateConfiguration.EventListeners.PreUpdateEventListeners = 
    new IPreUpdateEventListener[]{new AuditLogListener()};


//in my AuditLogListener
public class AuditLogListener : IPreUpdateEventListener
{
    public bool OnPreUpdate(PreUpdateEvent @event)
    {
        string message = //code to look at @event.Entity & build message - this works            
        if (!string.IsNullOrEmpty(message))
            AuditLogHelper.Log(message, @event.Session); //Session is an IEventSource

        return false; //Don't veto the change
    }
}

//In my helper
public static void Log(string message, IEventSource session)
{
    var user = session.QueryOver<User>()
                      .Where(x => x.Name == "John")
                      .SingleOrDefault();
    //have confirmed a valid user is found

    var logItem = new AdministrationAuditLog
                  {
                     LogDate = DateTime.Now,
                     Message = message,
                     User = user
                  };

    (session as ISession).SaveOrUpdate(logItem);
}

当它在最后一个方法中遇到session.SaveOrUpdate()时,不会发生错误。没有异常被抛出。它似乎成功并继续前进。但没有任何反应。审核日志条目永远不会出现在数据库中。

我能够通过它来创建一个全新的Session&amp; amp;这个方法中的事务,但这不是很理想,因为代码从监听器方法返回,在我的主应用程序中命中session.Transaction.Commit(),如果该事务失败,那么我有一个我的审计表中的孤立日志消息,表示从未发生过某种情况。

我可能出错的任何指示?

修改

我还尝试使用基于此线程中的一些注释的事件中的子会话来SaveOrUpdate LogItem。 http://ayende.com/blog/3987/nhibernate-ipreupdateeventlistener-ipreinserteventlistener

var childSession = session.GetSession(EntityMode.Poco);
var logItem = new AdministrationAuditLog
                {
                    LogDate = DateTime.Now,
                    Message = message,
                    User = databaseLogin.User
                };

childSession.SaveOrUpdate(logItem);

我的数据库中的日志表中仍然没有显示任何内容。没有错误或例外。

1 个答案:

答案 0 :(得分:3)

您需要在OnPreUpdate方法中创建子会话currentSession.GetSession(EntityMode.Poco),并在日志方法中使用它。根据您的flushmode设置,您可能还需要刷新子会话。

此外,您想推出自己的解决方案有什么特别的原因吗?仅供参考,NHibernate Envers现在是一个非常成熟的图书馆。