nhibernate-core icon indicating copy to clipboard operation
nhibernate-core copied to clipboard

Unable to perform AfterTransactionCompletion callback: System.NullReferenceException after update to 5.3.2 from 5.2.7

Open xumix opened this issue 3 years ago • 6 comments

This started after updating to 5.3.2 from 5.2.7. I can't create a repro since some tests work ok.

Stack Trace: 
    AfterTransactionCompletionProcessQueue.AfterTransactionCompletion(Boolean success)
    SessionImpl.AfterTransactionCompletion(Boolean success, ITransaction tx)
    AdoTransaction.AfterTransactionCompletion(Boolean successful)
    AdoTransaction.Commit()
// ......... Skipped
    TestHelper.Execute(Action action, Boolean useInterceptors) line 69
    StatisticsJobTests.Execute_ActiveCount_NoExceptions() line 414
    ----- Inner Stack Trace -----
    ReadOnlyCache.Clear()
    SessionFactoryImpl.EvictEntity(IEnumerable`1 entityNames)
    SessionFactoryExtension.EvictEntity(ISessionFactory factory, IEnumerable`1 entityNames)
    BulkOperationCleanupAction.EvictEntityRegions()
    BulkOperationCleanupAction.ExecuteAfterTransactionCompletion(Boolean success)
    AfterTransactionCompletionProcessQueue.AfterTransactionCompletion(Boolean success)

Config:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
      <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
      <!--<property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property>
      <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>-->
      <!--<property name="connection.driver_class">Granit.Core.Data.NHibernate.Oracle.OracleManagedDataClientDriver, Granit.Core</property>
      <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>-->
      <property name="connection.connection_string_name">Current</property>
      <property name="command_timeout">60</property>
      <property name="show_sql">false</property>
      <property name="format_sql">true</property>
      <property name="adonet.batch_size">100</property>
      <property name="cache.provider_class">NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache</property>
      <property name="cache.use_second_level_cache">true</property>
      <property name="cache.use_query_cache" >true</property>
    </session-factory>
  </hibernate-configuration>

What can this be caused by?

xumix avatar Sep 11 '20 13:09 xumix

The most likely case allowing a null reference exception in ReadOnlyCache.Clear is when it is called while the cache is already destroyed.

We should throw an InvaildOperationException instead. But it is also likely something quite wrong occurs in your application, causing the caches to be destroyed while the session factory or sessions it has opened are still in use. Caches are destroyed when the session factory is closed, so check the application is not disposing/closing the session factory before ceasing to use it or before ceasing to use a session opened by the disposed transaction factory. (All sessions must be disposed of/closed before disposing/closing the session factory.)

fredericDelaporte avatar Sep 11 '20 17:09 fredericDelaporte

@fredericDelaporte Thanks for the explanation! I checked my code: the factory is not disposed, the session is not disposed also. This happens on the transaction.Commit() event. Any other chance to get a clue for you to fix or for me to fix? :)

xumix avatar Sep 15 '20 14:09 xumix

A test case to reproduce this would be really helpful. Otherwise we would not be able to reproduce it. If we're not able to reproduce it, we are not be able to fix it.

hazzik avatar Sep 16 '20 11:09 hazzik

I checked my code: the factory is not disposed, the session is not disposed also.

How did you check it? Did you check factory.IsClosed when exception occurred?

bahusoid avatar Sep 17 '20 08:09 bahusoid

The NRE can still be seen as a regression, we should never have some. So I intend to PR a fix for replacing the NRE with proper exceptions in 5.3.x.

fredericDelaporte avatar Sep 18 '20 20:09 fredericDelaporte

Looks like we are in the same boat. When trying to run a direct DDL SQL command using SQL Query API, the code throws this very same exception. We are making use of SysCache and I am aware of the fact that any direct SQL update will result in cache invalidation. The code seemed to work well but now it throws this "Unable to perform AfterTransactionCompletion callback" error. Hopefully, I will be able to reproduce it via a test case.

mazharqayyum avatar Jan 17 '22 13:01 mazharqayyum