NHibernate Child Session not cleared correctly

We have implemented an audit system through NHibernate event listeners. In our listener, we track all changes and write them to our audit tables. To try to maximize performance, we used Guid for our audit tables so that we can update our updates as much as possible.

We write updates to the "child session", which we receive as follows:

 protected ISession GetSession(AbstractEvent @event)
 {
     if (@event == null)
     {
        throw new ArgumentNullException("event");
     }

        ISession childSession = @event.Session.GetSession(EntityMode.Poco);

        return childSession;
 } 

In the NHibernate documentation, this session should be a "child" session that inherits all of its parent's attributes — including the transaction.

Once we have created the object, we save it in the session with:

childSession.Save(auditLogEntry);

, , , childSession, . , , .

, , , ( ).

, , unit test, .

  public void When_Saving_Audit_Log_Records_To_Child_Session_Flushes_When_Transaction_Committed()
    {
        ISession session = GetSession();
        session.FlushMode = FlushMode.Commit;

        ITransaction transaction = session.BeginTransaction();

        ISession childSession = session.GetSession(EntityMode.Poco);

        AuditLogEntry entry = CreateAuditLogEntry();
        entry.AddAuditLogEntryDetail(CreateAuditLogEntryDetail());
        entry.AddAuditLogEntryDetail(CreateAuditLogEntryDetail());

        childSession.Save(entry);
        transaction.Commit();
    }

protected ISession GetSession()
    {
        return _sessionFactory.OpenSession();
    }

, NHibernate, - - , .

2 , , .

,

+3
2

FlushMode.Commit: NHibernate , . , , , .

, , FlushMode.Auto. , Auto, StackOverflowException / , Auto NHibernate , OnFlushDirty , , - OnFlushDirty, , OnFlushDirty . , FlushMode Never, , , , .

0

( GUID PK). PK Save INSERT , GUID , INSERT Flush. , NHibernate. SessionImpl.cs Flush ( 1467) :

// Flush children when parent is flushed.
if (childSessionsByEntityMode != null) {
    foreach (var childSession in childSessionsByEntityMode) {
        childSession.Value.Flush();
    }
}
0

Source: https://habr.com/ru/post/1755824/


All Articles