I use Spring.NET AOP for transaction and session management with NHibernate. When user makes several requests too quick – lazy loading is failed with exception “no session or session was closed”.
I use SpringSessionContext as CurrentSessionContext in NHibernate configuration
public class FluentSessionFactory : LocalSessionFactoryObject
{
protected override ISessionFactory NewSessionFactory(Configuration config)
{
var conf = Fluently
.Configure()
.Database(
MsSqlConfiguration
.MsSql2008
.ConnectionString(c => c.FromConnectionStringWithKey("MyConnection"))
// TODO: use ExposeConfiguration method
.CurrentSessionContext<SpringSessionContext>()
)
.Mappings(
m => m.FluentMappings
.AddFromAssembly(this.GetType().Assembly)
)
.BuildSessionFactory();
return conf;
}
}
In xml config:
<object id="SessionFactory" type="IndustryTracker.NHibernateRepository.FluentSessionFactory, IndustryTracker.NHibernateRepository">
<property name="DbProvider" ref="DbProvider" />
</object>
and OpenSessionInView module
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<add name="OpenSessionInView" type="Spring.Data.NHibernate.Support.OpenSessionInViewModule, Spring.Data.NHibernate31"/>
</modules>
</system.webServer>
Application implements next workflow for getting entities from db: View -> Controller -> Manager -> Repository and same to other side. So session is created per request, transaction – per call to manager.
<object id="TransactionManager" type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate31">
<property name="DbProvider" ref="DbProvider"/>
<property name="SessionFactory" ref="SessionFactory"/>
</object>
<tx:advice id="TxAdvice" transaction-manager="TransactionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<object id="Pointcut" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop">
<property name="patterns">
<list>
<value>MyAppication.Managers.AccountManager</value>
<value>MyAppication.Managers.CompanyManager</value>
</list>
</property>
</object>
<aop:config>
<aop:advisor advice-ref="TxAdvice" pointcut-ref="Pointcut"/>
</aop:config>
What are possible reasons of such behaviour and how can I solve this problem(Not.LazyLoad() and NHibernateUtil.Initialize() are not acceptable variants in my context)?
1. Session factory configured for
OpenSessionInViewModule?You might have forgotten to configure the session factory for the
OpenSessionInViewModule:This has to be done in the app settings.
2. Correct FluentNHibernate based spring session factory?
You seem to be configuring your session factory in code. Have you tried configuring the session factory like described in the docs and on BennyM ‘s blog? Your
NewSessionFactorymethod returns a session factory from straight from Fluent NHibernate, bypassing all spring.net support.3. Is your session factory transaction aware?
4. Does your controller have dependencies with
scope="application"or no scope definition?I might have been looking in the wrong direction here. If your controller has dependencies of
applicationscope, it would mean that quick requests could interfere. The default is"scope="application"; so you’d want to check collaborators without scope definitions too. See the docs on web scopes.