【发布时间】:2014-01-10 17:26:07
【问题描述】:
我正在对一些简单的审计日志记录功能进行原型设计。我有一个中型实体模型(约 50 个实体),我想在大约 5 或 6 个上实现审计日志记录。最终我也想让它在插入和删除上工作,但现在我只是专注于更新。
问题是,当我从 EventListener 中对我的 auditLog 表执行 session.Save(或 SaveOrUpdate)时,原始对象被正确保存(更新),但我的 AuditLog 对象永远不会被插入。
我认为 Pre 和 Post 事件侦听器在 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