Domanda

Sto prototizzando alcune semplici funzionalità di registrazione di audit. Ho un modello di entità medio di dimensioni (~ 50 entità) e mi piacerebbe implementare la registrazione di audit su circa 5 o 6. Alla fine vorrei far funzionare anche questo lavoro su inserti e cancellazioni, ma per ora sono solo Concentrandosi sugli aggiornamenti.

Il problema è, quando faccio sessione.Save (o salveUpdate) nella mia tabella Auditlog dall'interno dell'evento Eventener, l'oggetto originale è persistelato (aggiornato) correttamente, ma il mio oggetto Auditlog non viene mai inserito.

Penso che sia un problema con entrambi gli ascoltatori di eventi Pre e Post che vengono chiamati a tardi nel NHIBERNate Salva il ciclo di salvataggio per la sessione.

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

Quando colpisce la sessione.SaveORUpdate () nell'ultimo metodo, non si verificano errori. Non vengono lanciate eccezioni. Sembra avere successo e si muove. Ma non succede nulla. La voce del registro di audit non viene mai visualizzata nel database.

L'unico modo in cui sono stato in grado di ottenere questo per lavorarlo per creare una sessione e una transazione completamente nuova all'interno di questo metodo, ma questo non è davvero ideale, poiché il codice procede indietro del metodo listener, colpisce il session.Transaction.Commit () nella mia app principale, e se quella transazione fallisce, allora ho un messaggio di registro orfano nella mia tabella di audit per somethign che non è mai successo.

Qualche puntatori in cui potrei sbagliare?

Modifica

Ho anche provato a salvare il salvataggio del Logitem utilizzando una sessione figlio dagli eventi basati su alcuni commenti in questo thread. http://ayende.com/blog/3987/n-wibernate-ipreupdateeventListener-ipreinsertEventener

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

childSession.SaveOrUpdate(logItem);
.

Ancora niente appare nella mia tabella del registro nel DB. Nessun errore o eccezione.

È stato utile?

Soluzione

È necessario creare una sessione figlio, CurrentSession.getSession (ENTITYMode.POCO), nel tuo metodo OnPreUpdate e utilizzare questo nel tuo metodo di registro.A seconda dell'impostazione di Flushmode, potrebbe essere necessario scaricare anche la sessione figlio.

Inoltre, qualsiasi motivo particolare per cui vuoi svuotare la tua soluzione?FYI, Envita di Nibernate è ora una bella biblioteca matura.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top