2010-07-29 63 views
1

讓我先來介紹背景:ASP.NET的ObjectDataSource控件和NHibernate會話管理

在.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的會話和事務管理。下面是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」方法的一些電話是通過ObjectDataSource控件對象從ASP代碼所做的:

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

當我GETALL方法訪問的「CurrentSession」對象,我得到以下錯誤: 「無休眠SESS離子綁定到線程,配置不允許在這裏創建非事務性的配置「。 看來我的配置中缺少某些東西。

有關信息,我使用NHibernate 2.1.2 NET 3.5框架。我的數據庫是Oracle 11g。

任何幫助,將不勝感激!

回答

1

好吧,我想我找到了什麼錯。事實是我還沒有開始從頭開始編碼。我有一個已經開始工作的項目,但爲了使項目與多個SGBD一起工作,我必須重新構建數據訪問。因此,我使用NHibernate。由於我不是開始這個​​項目的人,所以我還沒有100%的知識來說明已經完成的工作,所以有一些NHibernate不喜歡的代碼。 例如,有在那裏與給定ID的對象是由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

您是否嘗試過線程Spring/Hibernate/JUnit - No Hibernate Session bound to Thread的解決方案,特別是第一個答案?

+0

感謝您的回覆。我不認爲這個解決方案是合適的,因爲我已經定義了一個交易管理器。我可能是錯的,但似乎這個解決方案只能用於JUnit。此外,我的問題是通過來自ASP.NET代碼的調用訪問NHibernate會話,因爲它可以從C#代碼中正常工作。 – Hal 2010-07-29 12:29:53

2

可以肯定的是,你的ClientDao類是Spring管理的嗎?所以當你從C#使用它時,一切正常。 但是你的ObjectDadaSource會使用反射來實例化一個新的ClientDao對象(Spring之外),所以你沒有你想要的東西(沒有DI,沒有AOP代理進行事務處理)。

可以

  • 使用ObjectDataSource控件類的事件ObjectCreating擺脫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你自己定製的「Spring」ObjectDataSource控件會自動從ApplicationContext獲取dao對象。這種方式非常靈活,您還可以在鏈接到gridview時以非常有效的方式管理分頁和排序。您可以定義很多方法將參數傳遞到您的dao方法以查詢數據(從會話,Spring表達式,其他彈簧服務等)。但這很難,需要先編碼一下......

希望這有助於

+0

奇怪的行爲... – Hal 2010-10-28 07:32:33