2012-03-06 95 views
2

后,我有以下声明代码不关闭会话:春天做NHibernate的交易

<tx:advice id="txAdvice" transaction-manager="TransactionManager"> 
    <tx:attributes> 
     <tx:method name="Get"/> 
     <tx:method name="Update"/> 
    </tx:attributes> 
</tx:advice> 

我调用方法“获取”和“更新”功能,从“X”。

方法“更新”抛出异常

春季如何关闭会话中执行方法后,“不同的对象具有相同标识符值已与会话关联”?

更新信息:

我会尝试更精确地描述问题。

我有mvc项目。 Conrolers称经理(他们代表业务逻辑)。经理使用存储库与数据库进行交互。 在更新动作我做以下事情:经理的

  • 调用get方法获取帐户
  • 改变一些性质在
  • 经理的电话更新方法updeting此帐户。

管理器的每个功能都被AOP包装到事务中。 当我调用Update方法时,它会写入错误。看起来这是因为Account对象仍附加到为Get函数打开的会话。 我试图直接在Get函数中打开和关闭会话(没有AOP)。所有作品在这种情况下都是正确

所以问题是为什么帐户对象仍然附加到会话后得到电话?

恕我直言,你不使用你的回购和春季接口未能建立AOP装饰。

我正在使用管理器界面。我测试了事务的回滚。它的工作原理,所以我认为AOP装饰器是建立。

+1

你从内部调用的方法同一个对象?你的nh会话范围如何配置? – Andreas 2012-03-06 13:55:35

+0

<对象ID = “NHibernateSessionFactory” 类型= “Woffer.NhibernateRepository.FluentSessionFactory,Woffer.NhibernateRepository”> <属性名= “DbProvider” REF = “DbProvider”/> <对象ID = “事务管理器” 类型= “Spring.Data.NHibernate.HibernateTransactionManager,Spring.Data.NHibernate31”> <属性名= “DbProvider” REF = “DbProvider”/> <属性名= “会话工厂” REF = “NHibernateSessionFactory”/> – christo 2012-03-06 14:01:45

+1

灿你请在你调用'Get'和'Update'的代码以及'Get'和'Update'的实现。 Imho你没有为你的Repo使用Interfaces,并且Spring未能构建AOP装饰器。 – Andreas 2012-03-06 16:51:14

回答

2

从评论到您的问题,我了解您的AOP代理已正确配置。我知道你有一个管理器类是这样的:

public class Manager : ISomeInterfaceToProxy 
{ 
    object Get(...) {} 
    void Update(object toUpdate) {} 
} 

这个管理器类与从你的问题的事务拦截劝。 该管理器被注入到您的控制器中,该控制器首先调用Get()(启动并完成第一个事务),然后调用Update(...)。认识到Update(...)的呼叫会启动第二笔交易,这可能会导致您在会话范围不是“每个请求”时提到的错误,这一点很重要。如果它找不到会话,则每个事务都将创建新会话。

有几种解决方案:

  1. 确保您的会话整个Web请求期间,如保持开放在视图中使用公开会议在spring.net nhibernate session/transaction per request
  2. 从另一个调用方法中的Get(...)Update(...)例程被包裹在一个事务的意见,从而使交易方法之间传播调用