2010-07-29 2 views
1

Позвольте мне описать контекст первого:ObjectDataSource в ASP.NET и управления NHibernate Session

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

Я написал запросы доступа к данным в 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 Sess ион, связанный с потоком, а конфигурация не позволяет создавать не транзакционные данные здесь ». Кажется, что-то отсутствует в моей конфигурации.

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

Любая помощь будет оценена!

ответ

1

Хорошо, я думаю, что я нашел то, что происходит не так. Дело в том, что я не начал кодировать с нуля. У меня был уже работающий проект, но мне пришлось перестроить доступ к данным, чтобы проект работал с несколькими 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 больным, потому что тот же сеанс содержит два объекта одного типа с одним и тем же идентификатором.

0

Вы пробовали решение по теме Spring/Hibernate/JUnit - No Hibernate Session bound to Thread, в частности, первый ответ?

+0

Спасибо за ваш ответ. Я не думаю, что это решение подходит, так как я уже определил менеджера транзакций. Возможно, я ошибаюсь, но похоже, что это решение должно работать только с JUnit. Более того, моя проблема заключается в доступе к сеансу NHibernate с вызовом из кода ASP.NET, поскольку он отлично работает с кодом C#. – Hal

2

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

Вы можете

  • использовать событие ObjectCreating класса ObjectDataSource, чтобы получить объект из ApplicationContext (подробнее здесь: http://www.rain-works.com/wpblog/index.php/2009/07/how-to-use-aspnet-object-data-source-with-ioc-spring-framework/)

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

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

Надеется, что это помогает

+0

Странное поведение ... – Hal

Смежные вопросы