NHibernate + Spring.NET lazy loading failed - no session

僤鯓⒐⒋嵵緔 提交于 2019-12-08 04:43:23

问题


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:


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.




回答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.



来源:https://stackoverflow.com/questions/10981625/nhibernate-spring-net-lazy-loading-failed-no-session

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!