Pregunta

Estoy creando un prototipo de una sencilla funcionalidad de registro de auditoría.Tengo un modelo de entidad de tamaño mediano (~50 entidades) y me gustaría implementar el registro de auditoría en aproximadamente 5 o 6.En última instancia, también me gustaría que esto funcione en Insertaciones y eliminaciones, pero por ahora sólo me estoy centrando en las actualizaciones.

El problema es que, cuando hago session.Save (o SaveOrUpdate) en mi tabla auditLog desde EventListener, el objeto original se conserva (actualiza) correctamente, pero mi objeto AuditLog nunca se inserta.

Creo que es un problema tanto con el Pre y Post Los oyentes de eventos son llamados demasiado tarde en el ciclo de vida de guardado de NHibernate para que la sesión aún se use.

//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);
}

Cuando llega a session.SaveOrUpdate() en el último método, no se producen errores.No se lanzan excepciones.parece tener éxito y sigue adelante.Pero nada pasa.La entrada del registro de auditoría nunca aparece en la base de datos.

La única forma en que he podido hacer que esto funcione es crear una sesión y transacción completamente nuevas dentro de este método, pero esto no es realmente ideal, ya que el código sale del método de escucha y llega a la sesión.Transacción .Commit() en mi aplicación principal, y si esa transacción falla, entonces tengo un mensaje de registro huérfano en mi tabla de auditoría por algo que nunca sucedió.

¿Algún consejo sobre dónde podría estar yendo mal?

EDITAR

También intenté SaveOrUpdate LogItem usando una sesión secundaria de los eventos según algunos comentarios en este hilo. 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);

Todavía no aparece nada en mi tabla de registro en la base de datos.Sin errores ni excepciones.

¿Fue útil?

Solución

Debe crear una sesión infantil, Currentsession.getSession (EntityMode.poco), en su método de onPreupdate y use esto en su método de registro.Dependiendo de su configuración de FLUSHMODE, es posible que deba lavar la sesión del niño también.

¡También, alguna razón en particular que desee desplegar su propia solución?FYI, NHIBERNATE ENVERS es ahora una biblioteca bastante madura.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top