【问题标题】:NHibernate IPreUpdateEventListener doesn't insert to second tableNHibernate IPreUpdateEventListener 不插入到第二个表
【发布时间】:2014-01-10 17:26:07
【问题描述】:

我正在对一些简单的审计日志记录功能进行原型设计。我有一个中型实体模型(约 50 个实体),我想在大约 5 或 6 个上实现审计日志记录。最终我也想让它在插入和删除上工作,但现在我只是专注于更新。

问题是,当我从 EventListener 中对我的 auditLog 表执行 session.Save(或 SaveOrUpdate)时,原始对象被正确保存(更新),但我的 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 & Transaction,但这并不理想,因为代码从监听器方法返回,点击session.Transaction.Commit() 在我的主应用程序中,如果该事务失败,那么我的审计表中会出现一条孤立的日志消息,说明从未发生过的事情。

我可能会出错的任何指针?

编辑

我还尝试使用基于此线程中某些 cmets 的事件中的子会话来保存或更新 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);

我的数据库中的日志表中仍然没有出现任何内容。没有错误或异常。

【问题讨论】:

  • 您需要在 OnPreUpdate 方法中创建一个子会话 currentSession.GetSession(EntityMode.Poco) 并在您的日志方法中使用它。
  • 另外,您想推出自己的解决方案有什么特别的原因吗?仅供参考,NHibernate Envers 现在是一个相当成熟的库。
  • 刚刚尝试过...查看问题的编辑
  • (现在猜测)根据您的刷新模式设置,您可能还需要刷新子会话。
  • 超级巨星! :-) 只是在子会话中缺少.Flush()。为此欢呼。至于 Envers 项目。甚至不知道它的存在。也会去解决这个问题。谢谢罗杰。如果您想在答案中保留您的 2 条建议,我会给您打勾

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


【解决方案1】:

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

另外,您想推出自己的解决方案有什么特别的原因吗?仅供参考,NHibernate Envers 现在是一个相当成熟的库。

【讨论】:

  • 我的 FlushMode 是 Auto,但我仍然需要在 childsession 上调用 .Flush()。这是为什么呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-15
  • 2019-06-09
  • 2022-01-07
相关资源
最近更新 更多