【发布时间】:2014-10-23 12:42:49
【问题描述】:
我正在将应用程序从 Hibernate 3.3 升级到 Hibernate 4.2。我们也在使用 Spring 3.1.3(我们目前无法/不会更新)。
我的一些单元测试现在失败了
org.hibernate.HibernateException: No Session found for current thread
在 SpringSessionContext 中。这不是 <tx:annotation-driven /> 在错误上下文中定义的问题,也不是缺少 CGLIB 库的情况。大多数测试确实有效,这意味着在大多数情况下,事务代理正在工作。
现在失败的情况似乎与使用 NOT_SUPPORTED、NEVER 和 SUPPORTED 传播类型有关。无论出于何种原因,SpringSessionContext 在这些情况下都不会创建会话。
我们的用例有时要求事务边界不与方法边界严格对齐,并且会话有时会比事务长。在 Spring 3/Hibernate 3 的情况下,会话上下文被绑定到本地线程,即使事务没有启动,对 SessionFactory.getCurrentSession() 的调用也会返回一个会话实例。这是我希望在 Hibernate 4 案例中仍然具有的行为。
有人知道解决方法吗?如果 Spring 拒绝在没有有效事务的情况下创建会话,则很难将会话边界与会话而不是事务对齐。 Session 及其持久性上下文不应绑定到打开的事务。
【问题讨论】:
-
所提到的传播类型永远不会触发事务的创建或会话的查找。会话绑定到事务边界。如果这是否正确,已经进行了一些讨论,并且在该领域已经进行了工作,但仅适用于较新版本的 Spring。
-
为什么不需要传播的工作?如果没有现有的交易,就会进行交易,或者使用现有的交易,这听起来像你想要的。
-
Propagation.REQUIRED 并不适用于所有情况。例如,我们有一个执行多个事务的方法。我们将方法上的事务边界设置为 NEVER 或 NOT_SUPPORTED 以确保调用此方法时没有启动事务。然后该方法使用平台事务管理器开始/提交事务。但是,即使在这种情况下 sessionFactory.getCurrentSession() 也会返回 null 并强制异常。这似乎是一个相当大的问题,因为 HibernateTransactionManager 被注入了相同的会话工厂。
-
你确实意识到你正在设置一些东西,所以你不会有交易,然后抱怨你没有交易?我认为您需要此类事情需要新的(您可能必须将代码分解为单独的方法,以便每个方法都获得新的事务)。
-
我不是在抱怨我没有交易,我在抱怨我没有会话。会话应该能够独立于事务存在,并且比事务存在更长的时间。 Hibernate 3 中使用的会话上下文绑定到本地线程,并且无论是否有已启动的事务,对 sessionFactory.getCurrentSession() 的调用都有效。这是我们所依赖的功能,也是我希望继续依赖的功能。
标签: spring hibernate transactions