Domanda

Sto utilizzando gli intercettori NHibernate per registrare informazioni su aggiornamenti/inserimenti/eliminazioni nelle mie varie entità.

Nelle informazioni registrate sono inclusi il tipo di entità e l'ID univoco dell'entità modificata.L'ID univoco è contrassegnato come a <generator class="identity"> nel file di mappatura di Hibernate.

Il problema ovvio è che quando si registra un'operazione di inserimento utilizzando IInterceptor.OnSave() l'ID dell'entità non è stato ancora assegnato.

Come posso ottenere l'ID dell'entità inserita prima di registrare le informazioni di audit?

(Ho esaminato l'evento PostSave di NHibernate Listeners ma non riesco a farli funzionare con la configurazione Spring.net utilizzata, quindi vorrei restare con gli interceptor se possibile)

Codice:

    // object id parameter is null...
    public override bool OnSave(object entity, object id, object[] state, 
        string[] propertyNames, IType[] types)
    {            
        AddAuditItem(entity, INSERT);
        return false;            
    }
È stato utile?

Soluzione

Ho risolto questo problema aggiungendo un elenco alla mia classe interceptor che viene popolata con oggetti durante il file OnSave implementazione.

Nel PostFlush implementazione l'elenco viene ripetuto e ogni elemento viene controllato come un inserto.Gli oggetti in questo elenco sono stati resi persistenti PostFlush() e quindi hanno generato ID.

Sembra funzionare bene, ma sarei grato se venissero segnalati eventuali trappole :-)

public class AuditInterceptor : EmptyInterceptor
{       
    // To hold inserted items to be audited after insert has been flushed
    private IList<object> insertItems = new List<object>();

    public override void PostFlush(System.Collections.ICollection entities)
    {            
        foreach (var entity in insertItems)
        {
            AddAuditItem(entity, INSERT);
        }
        insertItems.Clear();

        base.PostFlush(entities);
    }

    public override bool OnSave(object entity, object id, object[] state, 
        string[] propertyNames, IType[] types)
    {            
        var auditable = entity as IAuditable;
        if (auditable != null) 
            insertItems.Add(entity);

        return false;            
    }
}

Altri suggerimenti

provare il metodo OnFlushDirty .. o forse PostFlush

modifica: anche, puoi pubblicare il tuo codice? Non si ottiene l'Es come parametro per OnSave?

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