1

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)?

2 Answers 2

2

After some search I found that problem was in configuration. There was spring WebSupportModule missing http module in config, so the correct one is:

    <httpModules>
      <add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
      <add name="OpenSessionInView" type="Spring.Data.NHibernate.Support.OpenSessionInViewModule, Spring.Data.NHibernate31"/>  
    </httpModules>

So Marijn was right - it was weak wiring to spring.

Sign up to request clarification or add additional context in comments.

Comments

1

1. Session factory configured for OpenSessionInViewModule?

You might have forgotten to configure the session factory for the OpenSessionInViewModule:

<appSettings>
  <add key="Spring.Data.NHibernate.Support.OpenSessionInViewModule.SessionFactoryObjectName" 
       value="SessionFactory"/>
</appSettings>

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 NewSessionFactory method returns a session factory from straight from Fluent NHibernate, bypassing all spring.net support.

3. Is your session factory transaction aware?

<object id="SessionFactory" 
        type="IndustryTracker.NHibernateRepository.FluentSessionFactory, IndustryTracker.NHibernateRepository">
  <property name="DbProvider" ref="DbProvider" />
  <!-- provides integation with Spring's declarative transaction management features -->
  <property name="ExposeTransactionAwareSessionFactory" value="true" /> 
</object>

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 application scope, 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.

7 Comments

Thanks, it wasn't configured indeed. But fixing it didn't solve my problem.
Updated my answer. Please post your session factory configuration too.
I've posted session factory configuration. As I understood - BennyM's post is for configuration of mappings. Can wrong mappings configuration be the reason?
I don't think mapping issues are the problem, because then you would get an exception on application startup. I think your session factory isn't correctly wired to spring.
I've set the property, described in your third update, but it also didn't help. About wiring to spring - it works great when doing request with normal speed, but crashes if make requests too quickly (for example multiple clicking on button).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.