views:

129

answers:

1

I'm profiling out unit & integration tests, and I find the a lot of the time is spent on the finalizer of NHibernate.Transaction.AdoTransaction - this means it is not getting disposed properly.

I am not using AdoTransaction directly in the code, so it's probably used by some other object inside NHibernate. Any idea what I'm forgetting to Dispose?

Here is my text fixture:

public abstract class AbstractInMemoryFixture
{
    protected ISessionFactory sessionFactory;
    protected ILogger Logger { get; private set; }
    static readonly Configuration config;
    private static readonly ISessionFactory internalSessionFactory;

    static AbstractInMemoryFixture()
    {
     config = new NHibernateConfigurator().Configure(NHibernateConfigurators.SQLiteInMemory());
     internalSessionFactory = config.BuildSessionFactory();
    }

    [SetUp]
    public void SetUp()
    {
        const string sqliteInMemoryConnectionString = "Data Source=:memory:;Version=3;Pooling=False;Max Pool Size=1;";
        var con = new SQLiteConnection(sqliteInMemoryConnectionString);
     con.Open();
        new SchemaExport(config).Execute(false, true, false, true, con, System.Console.Out);
     var proxyGenerator = new ProxyGenerator();

     sessionFactory = proxyGenerator.CreateInterfaceProxyWithTarget(internalSessionFactory, new UseExistingConnectionInterceptor(con));
        Logger = new NullLogger();

        ExtraSetup();
    }

    [TearDown]
    public void TearDown()
    {
     var con = sessionFactory.OpenSession().Connection;
     if (con != null)
     {
      if (con.State == ConnectionState.Open)
       con.Close();
      con.Dispose();
     }
    }

    private class UseExistingConnectionInterceptor :IInterceptor
    {
     private readonly SQLiteConnection connection;

     public UseExistingConnectionInterceptor(SQLiteConnection connection)
     {
      this.connection = connection;
     }

     public void Intercept(IInvocation invocation)
     {
      if (invocation.Method.Name != "OpenSession" || invocation.Method.GetParameters().Length > 0)
      {
       invocation.Proceed();
       return;
      }
      var factory = (ISessionFactory) invocation.InvocationTarget;
      invocation.ReturnValue = factory.OpenSession(connection);
     }
    }
    protected virtual void ExtraSetup() { }
}
A: 

I have the same problem while accessing a Sybase database. I don't know why, nor if it's really the reason of the issue, but it appears that some of the code in \NHibernate\Transaction\AdoTransaction.cs (lines 307 to 311) related to closing/disposing the object have been disabled for a while. Unfortunately, the blame feature of SVN does not give too much info :(

Yann Trevin