我正在制作一些简单的审计日志功能的原型。我有一个中型实体模型(约 50 个实体),我想在大约 5 或 6 个上实施审计日志记录。最终我也想让它在插入和删除上工作,但现在我只是专注于更新。
问题是,当我从 EventListener 中对我的 auditLog 表执行 session.Save(或 SaveOrUpdate)时,原始对象被正确保存(更新),但我的 AuditLog 对象永远不会被插入。
我认为在 NHibernate 保存生命周期的后期调用事件侦听器Pre
和事件侦听器是一个问题,以便会话仍然可以使用。Post
//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() 在我的主应用程序中,如果该事务失败,那么我的审计表中会出现一条孤立的日志消息,说明从未发生过的事情。
我可能会出错的任何指示?
编辑
我还尝试使用基于此线程中的一些评论的事件中的子会话来保存或更新 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);
我的数据库中的日志表中仍然没有出现任何内容。没有错误或异常。