sreenivask
05-13-2007, 07:57 PM
Mark:
We have used Spring's HibernateTemplate services to develop the DAO layer of a large business application. The Services/persistence layer has around 800K lines of C# code. There are aproxmiately 1100 DAO classes (each inheriting from HibernateDaoSupport) in this layer.
Due to issues of change management that we could not solve, we decided not to use DI. And, we ended up hardwiring the DAOs to the Service Layer. :(
Each service call, therefore, results in the creation of a new DAO object. And--here is crux of the problem--each DAO object creates a ProxyFactory for the Session object that Execute and ExecuteFind pass as a parameter to Anonymous Delegates).
Normal testing--10 testers concurrently testing different services--creates a load of around 10-20 business transactions per minute. That is, around 60 calls to the DAOs resulting in the creation of 60 ProxyFactories per minute and these never get garbage collected. Using WinDbg we found that 95% of the GC heap is occupied by these ProxyFactories.
We set HibernateTemplate.ExposeNativeSession = true as a temporary fix. This stopped the growth of the heap, but will make the solution vulnerable to bugs caused by inadvertent closure of the session within the delegates.
What would be a more permanent fix?
Even if we were to use DI to inject the DAO (singleton) into the Services layer, it would still result in the creation of 1100 proxyfactories (one for each DAO) for the session object, since CreateSessionProxy() is unaware of ProxyFactories created by other instances of HibernateTemplate. How can we make HibernateTemplate.CreateSessionProxy() be aware of the other ProxyFactories?
Can we change the visibility of "HibernateTemplate.sessionProxyFactory" to public and use DI to inject the proxyfactory into HibernateTemplate in each DAO?
Sreenivas K.
We have used Spring's HibernateTemplate services to develop the DAO layer of a large business application. The Services/persistence layer has around 800K lines of C# code. There are aproxmiately 1100 DAO classes (each inheriting from HibernateDaoSupport) in this layer.
Due to issues of change management that we could not solve, we decided not to use DI. And, we ended up hardwiring the DAOs to the Service Layer. :(
Each service call, therefore, results in the creation of a new DAO object. And--here is crux of the problem--each DAO object creates a ProxyFactory for the Session object that Execute and ExecuteFind pass as a parameter to Anonymous Delegates).
Normal testing--10 testers concurrently testing different services--creates a load of around 10-20 business transactions per minute. That is, around 60 calls to the DAOs resulting in the creation of 60 ProxyFactories per minute and these never get garbage collected. Using WinDbg we found that 95% of the GC heap is occupied by these ProxyFactories.
We set HibernateTemplate.ExposeNativeSession = true as a temporary fix. This stopped the growth of the heap, but will make the solution vulnerable to bugs caused by inadvertent closure of the session within the delegates.
What would be a more permanent fix?
Even if we were to use DI to inject the DAO (singleton) into the Services layer, it would still result in the creation of 1100 proxyfactories (one for each DAO) for the session object, since CreateSessionProxy() is unaware of ProxyFactories created by other instances of HibernateTemplate. How can we make HibernateTemplate.CreateSessionProxy() be aware of the other ProxyFactories?
Can we change the visibility of "HibernateTemplate.sessionProxyFactory" to public and use DI to inject the proxyfactory into HibernateTemplate in each DAO?
Sreenivas K.