Spring.net с NHibernate и «Нет Hibernate Session связан с ошибкой потока» - PullRequest
5 голосов
/ 22 февраля 2010

Я пытаюсь использовать spring.net и nihibernate для своего слоя данных.

У меня есть простой объект DAO, который включает следующий код:

[Transaction]
public long Save(Request entity)
{
   return (long)CurrentSession.Save(entity);    
}

Всякий раз, когда вызывается этот код, я получаю следующую ошибку:

«Сеанс Hibernate не привязан к потоку, и конфигурация не позволяет создавать нетранзакционный сеанс здесь»

Мой уровень DAO имеет следующую конфигурацию, на которую ссылается мой web.config:

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net"
         xmlns:tx="http://www.springframework.net/tx"
         xmlns:db="http://www.springframework.net/database"
         xmlns:aop="http://www.springframework.net/aop"
         >

  <!-- Referenced by main application context configuration file -->
  <description>
    The Northwind object definitions for the Data Access Objects.
  </description>

  <!-- Property placeholder configurer for database settings -->
  <object type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core">
    <property name="ConfigSections" value="databaseSettings"/>
  </object>

  <!-- Database and NHibernate Configuration -->
  <db:provider id="DbProvider"
                   provider="SqlServer-2.0"
                   connectionString="Data Source=ME-LT;Initial Catalog=SupplyAndDemand;Integrated Security=True"/>

  <object id="NHibernateSessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate21">
    <property name="DbProvider" ref="DbProvider"/>
    <property name="MappingAssemblies">
      <list>
        <value>SAD.Providers.NHibernate</value>
      </list>
    </property>
    <property name="HibernateProperties">
      <dictionary>

        <entry key="connection.provider"
               value="NHibernate.Connection.DriverConnectionProvider"/>

        <entry key="dialect"
               value="NHibernate.Dialect.MsSql2005Dialect"/>

        <entry key="connection.driver_class"
               value="NHibernate.Driver.SqlClientDriver"/>

      </dictionary>
    </property>

    <property name="ExposeTransactionAwareSessionFactory" value="true" />
  </object>


  <object id="transactionManager"
        type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate21">
    <property name="DbProvider" ref="DbProvider"/>
    <property name="SessionFactory" ref="NHibernateSessionFactory"/>

  </object>

  <!-- Data Access Objects -->
  <object id="RequestDao" type="SAD.Providers.Nhibernate.NHibernateRequestDao, SAD.Providers.Nhibernate">
    <property name="SessionFactory" ref="NHibernateSessionFactory" />
  </object>


<tx:attribute-driven transaction-manager="transactionManager"/>

</objects>

В моем web.config я включил ссылку на парсер:

<parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data"/>

и ссылался на мой dao.xml как ресурс сборки.

Этот DOA вводится в другой объект, настроенный пружиной, из которого вызывается Save.

Есть идеи, что я делаю не так? Как вы видите, я включаю конфиг

<tx:attribute-driven transaction-manager="transactionManager"/> 

Я прикрепил к пружинному коду и поместил точку останова в метод invoke TransactionInterceptor - он никогда не вызывается - так что, возможно, прокси не создается для моих объектов dao?

Вот полная трассировка стека:

<StackTrace><![CDATA[at Spring.Data.NHibernate.SpringSessionContext.CurrentSession() in F:\Spring.NET\Spring.NET\src\Spring\Spring.Data.NHibernate12\Data\NHibernate\SpringSessionContext.cs:line 70
   at NHibernate.Impl.SessionFactoryImpl.GetCurrentSession()
   at sad.Providers.Nhibernate.NHibernateDao.get_CurrentSession() in F:\PersonnalProjects\sad\trunk\src\sad\sad.Providers.Nhibernate\nHibernateDao.cs:line 29
   at sad.Providers.Nhibernate.NHibernateRequestDao.Save(Request entity) in F:\PersonnalProjects\sad\trunk\src\sad\sad.Providers.Nhibernate\NHibernateRequestDao.cs:line 41
   at sad.Messaging.RequestManager.RequestManager.ProcessRequest(UserCredentials userCredentials, Request request) in F:\PersonnalProjects\sad\trunk\src\sad\sad.Messaging.RequestManager\RequestManager.cs:line 39
   at sad.Messaging.UI.Web.RequestManagerService.ProcessRequest(UserCredentials userCredentials, Request request) in F:\PersonnalProjects\sad\trunk\src\sad\sad.Messaging.UI.Web\RequestManagerService.cs:line 28
   at requestManagerService.ProcessRequest(UserCredentials userCredentials, Request request)
   at SyncInvokeProcessRequest(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)

1 Ответ

2 голосов
/ 11 августа 2010

Я знаю, что это старый вопрос, но есть ли у вас модуль Open Session In View, определенный в вашем файле web.config?

Для IIS6 должно быть что-то вроде:

<httpModules>
    <!-- Other modules here -->
    <add name="OpenSessionInView" type="Spring.Data.NHibernate.Support.OpenSessionInViewModule, Spring.Data.NHibernate21"/>
</httpModules>

Кроме того, я могу ошибаться по этому поводу, но я думаю, что Open Session In View ищет фабрику сеансов с именем (как вы уже догадались) SessionFactory, и поэтому вам также может понадобиться добавить это и в web.config:

<appSettings>
    <!-- Other App Settings -->
    <add key="Spring.Data.NHibernate.Support.OpenSessionInViewModule.SessionFactoryObjectName" value="NHibernateSessionFactory"/>
</appSettings>
...