2010-07-29 64 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