ASP.NET ObjectDataSource и NHibernate Session Management - PullRequest
2 голосов
/ 29 июля 2010

Позвольте мне сначала описать контекст:

В проекте .NET C # я использую NHibernate, чтобы установить связь между объектами C # и моделью базы данных.Я сопоставил свои объекты с помощью атрибутов сопоставления NHibernate.

Я написал запросы доступа к данным на HQL, все они изолированы в отдельных методах, которые украшены атрибутами для управления транзакциями.Вот как выглядят мои классы доступа к данным:

namespace MyProject.DataAccess
{
    public class ClientDao
    {
         private ISessionFactory sessionFactory;
         public ISessionFactory SessionFactory
         {
             protected get { return sessionFactory; }
             set { sessionFactory = value; }
         }

         protected ISession CurrentSession
         {
             get { return sessionFactory.GetCurrentSession(); }
         }

         [Transaction(TransactionPropagation.Required, IsolationLevel.ReadCommitted)]
         public IList<Client> GetAll()
         {
             return CurrentSession.CreateQuery("from Client c").List<Client>();
         }
    }    
}

Я настроил управление сессиями и транзакциями Nhibernate с помощью Spring.Вот конфигурация xml:

<!-- NHibernate Configuration -->
<object id="NHibernateSessionFactory" type="GeSuiPro.Abstract.ExtendedSessionFactoryObject, GeSuiPro.Abstract">
  ...

  <property name="HibernateProperties">
  ...
  </property>

  <!-- provides integation with Spring's declarative transaction management features -->
  <property name="ExposeTransactionAwareSessionFactory" value="true" />
</object>

<!-- Transaction Management Strategy - local database transactions -->
<object id="transactionManager"
    type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate21">

  <property name="DbProvider" ref="DbProvider"/>
  <property name="SessionFactory" ref="NHibernateSessionFactory"/>

</object>

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

<!-- Exception translation object post processor -->
<object type="Spring.Dao.Attributes.PersistenceExceptionTranslationPostProcessor, Spring.Data"/>

Теперь, когда я пытаюсь получить доступ к сеансу из кода C #, все работает нормально:

IList<Client> list = clientDao.GetAll();

Однако некоторые вызовы "GetAll "методы создаются из кода ASP через объекты ObjectDataSource:

<asp:ObjectDataSource ID="odsClient" runat="server" TypeName="MyProject.DataAccess.ClientDao"
            SelectMethod="GetAll" DataObjectTypeName="MyProject.Object.Client" />

При доступе к объекту" CurrentSession "в моем методе GetAll я получаю следующую ошибку:" Сессия Hibernate не связана с потокомконфигурация не позволяет создавать здесь нетранзакционную ».Кажется, что-то отсутствует в моей конфигурации.

Для информации я использую .NET 3.5 Framework с NHibernate 2.1.2.Моя база данных - Oracle 11g.

Буду признателен за любую помощь!

Ответы [ 3 ]

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

просто чтобы быть уверенным, ваш класс ClientDao управляется Spring, верно? Поэтому, когда вы используете его из C #, все в порядке. Но ваш ObjectDadaSource создаст экземпляр нового объекта ClientDao, используя отражение (вне Spring), поэтому у вас нет того, что вы хотите (без DI, без прокси-сервера AOP для транзакций).

Вы можете

  • использовать событие ObjectCreating класса ObjectDataSource для получения объекта из ApplicationContext (подробнее здесь: http://www.rain -works.com / wpblog / index.php / 2009/07 / how-to- потребительная Сеть САШИ-объект-источник данные-с-IoC-пружинные рамками / )

  • обернуть вызовы объекта DAO в статические методы статического класса, который «знает» о Spring и чем использовать эти статические методы из ObjectDataSource (объект DataSourceObject не создается со статическими методами)

  • написать свой собственный элемент управления «Spring» ObjectDataSource, который будет автоматически получать объект dao из ApplicationContext. Этот способ очень гибок, и вы также можете управлять поиском, сортировкой очень эффективным способом при связывании с видом сетки. Вы можете определить множество способов передачи аргументов вашим дао-методам для запроса данных (из сеанса, Spring-выражения, других Spring-сервисов и т. Д.). Но это сложнее и требует сначала немного кодирования ...

Надеюсь, это поможет

1 голос
/ 28 октября 2010

Хорошо, я думаю, что нашел, что идет не так.Дело в том, что я не начал писать код с нуля.У меня был уже работающий проект, но мне пришлось пересобрать доступ к данным, чтобы проект работал с несколькими SGBD.Таким образом, я использовал NHibernate.Поскольку я не тот, кто начал проект, я не на 100% знаю, что было сделано до сих пор, поэтому был какой-то фрагмент кода, который не понравился NHibernate.Например, был случай, когда объект с заданным идентификатором был загружен сеансом NHibernate, и где-то еще в коде объект был заново создан и затем обновлен:

MyObject a = session.createQuery("from MyObject m where m.Id = 0");

И где-то ещев коде:

MyObject a = new MyObject();
a.Id = 0;
session.Update(a);

Это делает NHibernate больным, потому что один и тот же сеанс содержит две сущности одного типа с одинаковым Id.

0 голосов
/ 29 июля 2010

Пробовали ли вы решение в потоке Spring / Hibernate / JUnit - с Hibernate Session не связан поток , в частности первый ответ?

...