Hello,
I've been using iBATIS for a couple of months now, it's a nice framework so thanks for the hard work. I'm currently using 1.5.1 + 1.8.1 of the mapper/access layer, but verified the following works the same in the newest beta versions. I've run into what appears to be a bug in the DataAccess session handling setup, but if I'm approaching this incorrectly I'm looking for suggestions. The basic thing I want to do is have an independent connection that I can use to log status and errors to a database without being affected by the success/fail of any existing transaction in progress, and without having to affect the code outside of the database logger with respect to transactions. The most obvious way I see to do this with support from iBATIS is to define a separate Dao context for logging. This is where I ran into a problem.

If I have multiple DAO contexts defined and attempt to open or start a transaction on more than one context on the same thread I am receiving the "session already option / transaction already started" exception. I setup a test similar to the MultipleDAOTest in the iBATIS test cases like so:
      [Test]
      public void TestMultipleDAO()
      {
          DomDaoManagerBuilder builder = new DomDaoManagerBuilder();
          builder.Configure("dao.config");

          IDaoManager mgr1 = DaoManager.GetInstance("Context1");
          IDaoManager mgr2 = DaoManager.GetInstance("Context2");
          IPatronDAO pDao = mgr1[typeof(IPatronDAO)] as IPatronDAO;
          ILogDAO lDao = mgr2[typeof(ILogDAO)] as ILogDAO;

          mgr1.OpenConnection();
mgr2.OpenConnection(); <--- this is where the exception is thrown
          ...
          mgr1.CloseConnection();
          mgr2.CloseConnection();
      }

I traced this into the iBATIS source, and see that when the DomDaoManagerBuilder creates a DaoManager instance (DaoManager.NewInstance), the internal DaoManager constructor is invoked, which immediately calls SessionStoreFactory with the DaoManager id to create a session store. The problem appears to be that the call to the SessionStoreFactory will always receive an empty string for id of the Dao Context, since DomDaoManagerBuilder::GetContexts() doesn't actually set the context id until after DaoManager.NewInstance() returns. As a result, sessions for all contexts on the same thread are keyed on the default string _IBATIS_LOCAL_DAOSESSION_ from AbstractSessionStore, which I confirmed through VS2005 debugging. As soon as you create one session (openconnection or begintransaction), all contexts' LocalDaoSession reference this session because the sessionName is the same for all.

DataMapper does not appear have this problem because in constructing a mapper the id is set during construction, prior to calling the session store factory.

My hope is that I'm doing something wrong, and would welcome the assistance.
Thank you, Shane

Reply via email to