Reputation: 69983
I have a web app that uses the iBATIS.NET library.
The DAO is configured by using an XmlDocument, so the code is very similar to what they show in the documentation:
XmlDocument anXmlDoc = someSupportClass.GetDynamicXmlDocument();
DomDaoManagerBuilder builder = new DomDaoManagerBuilder();
builder.Configure(anXmlDoc);
The documentation says right below that:
The DaoManager instance that is built from a dao.config file is aware of all of the contexts contained within the configuration file. The context basically bundles DAO implementations together with a session handler. The DaoManager knows which DAOs and session handler belong to which context. When you request a DAO instance from the DaoManager, the proper session handler will be provided with it. Therefore, there is no need to access the context or session handler directly. Your DAO knows how it works.
This does not appear to be true. In a threaded process, the following exception is thrown randomly:
WebSessionStore: Could not obtain reference to HttpContext at IBatisNet.DataAccess.SessionStore.WebSessionStore.ObtainSessionContext() at IBatisNet.DataAccess.SessionStore.WebSessionStore.get_LocalSession()
at IBatisNet.DataAccess.DaoManager.IsDaoSessionStarted() at IBatisNet.DataAccess.Configuration.DaoProxy.Intercept(IInvocation invocation, Object[] arguments)
The application may run fine for days or even months at a time, but every once in awhile this exception is thrown. The only solution I can find mentioned anywhere is to swap out the SessionStore for a HybridWebThreadSessionStore
(mentioned here).
As the documentation says above, this shouldn't be necessary. If I wanted to force it though, how would I go about overriding the SessionStore created by the DomDaoManagerBuilder
?
Upvotes: 0
Views: 1311
Reputation: 321
The error occurred because you run ibatis in different threads. You can make use of a new instance of HybridWebThreadSessionStore just before making a query to the database.
var map = new Hashtable
{
{ "FilterA", "MyFilter" }
};
SqlMap.SessionStore = new HybridWebThreadSessionStore(SqlMap.Id);
var listadoJobs = SqlMap.QueryForList<EventoJob>(SbsIbatisConstantes.ListarJobs, map).ToList();
You can check this reference Here
That worked for me.
Upvotes: 0
Reputation: 69983
The issue seems to be caused by a race condition in the iBatis.NET framework when the application starts up. If a call to the database is made on the main thread before a call to the database is made on a separate thread, then the separate threads will raise the error since they don't have an HttpContext stored in the SessionStore.
Basically it went Startup -> db call on main thread -> db call on separate thread
When it should have been Startup -> db call on separate thread -> db call on main thread
Basically I just changed the order in which events fire to make sure the db call on the thread is called at least once before anything on the main thread happens.
This post describes the same problem
THE SETUP
In my Global.asax, I kick-start a background process using the Timer class. This Timer class uses a delgate DoTimerBasedStuff() which is called periodically. The DoTimerBasedStuff() method accesses two different databases, MySQL and SQL Server. Both are setup properly using their MySQLMapper and SQLServerMapper classes.
Aside from a couple of these background threads, the application also has a web front which accesses both databases using typical .aspx pages and classes inherited from Page. Nothing fancy.
THE PROBLEM
If the application is started by going to index.aspx using a browser (this page doesn't do any db stuff but triggers Global.asax) and no other actions are taken until the first call of DoTimerBasedStuff() all is well and both the background process and the web users are fine. IBatis does everything right.
BUT if I start the application by going to index.aspx and then immediately do some work via the web which accesses a database (before DoTimerBasedStuff() is executed), the DoTimerBasedStuff() method has trouble accessing the HttpContext and gives the following error:
Exception: WebSessionStore: Could not obtain reference to HttpContext at IBatisNet.DataMapper.SessionStore.WebSessionStore.ObtainSessionContext() at IBatisNet.DataMapper.SessionStore.WebSessionStore.get_LocalSession() at IBatisNet.DataMapper.SqlMapper.QueryForObject(String ...
Upvotes: 1