求Spring(3.0.5)解决方案:没有Hibernate会话绑定到线程,配置不允许在这里创建非事务性的

时间:2011-02-27 19:05:43

标签: java hibernate spring transactions spring-aop

我在Spring 3.0.5上遇到了一个Transaction问题。在我的情况下,我得到所谓的异常“没有Hibernate会话绑定到线程,配置不允许在这里创建非事务性的”...到目前为止我已经尝试了一切。我可以在我的日志中看到事务服务被检测到并注册为Spring bean,我还可以在日志中看到它们被代理并与基础Spring事务拦截器相关联。 (建议)当我运行我的Spring MVC应用程序时,我的控制器将调用服务...... :-(但是事务拦截器没有被触发。(??)我希望我的Spring服务代理打开一个会话并启动一个在调用我的目标服务方法之前的事务。由于这没有发生,我得到了上述异常。我已经差不多两天了解这个问题。试过我在互联网上发现的一切......但是徒劳无功。

我有分层架构:presentation(springmvc),service(事务注释),dataacess(Spring / Hibernate经典sessionfactory)。我的模型对象用jpa(javax.persistence。*)注释。我的spring上下文配置文件在appContext.xml,appContext-service.xml和appContext-dao.xml中分开。我在appContext-dao.xml中定义了我的Spring LocalSessionFactoryBean,Datasource和TransactionManager(HibernateTransactionManager)。我已经放入了我的服务实现所在的appContext-service.xml。在我的所有配置文件中,我已经包含并通过Controller,Service和Repository注释来检测我的bean。

我感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

听起来你正在做正确的事,你知道自己在做什么。除非你展示一些配置,否则我们在这里做的不多。

我建议的是一些调试。

首先:您是否在服务层中进行了单元测试,以测试您正在使用的查询?也许你可以在服务层找到错误。

然后:调试MVC应用程序,检查注入服务的类型。验证它们是代理,而不是原始类型。

  • 如果他们是原始类型,你 您的交易中有错误 配置。
  • 如果他们是代理人,请逐步完成 查询方法并验证 应用了交易逻辑。

答案 1 :(得分:0)

这听起来像是在交易结束后访问延迟加载的列表或你的dao集。如果您在视图中访问该列表而不是控制器,则通常会发生这种情况,因为您的控制器可能会调用事务范围中的方法,然后离开事务并将加载的bean转发到视图。

简单的解决方案:

  • 配置您的数据bean以急切加载
  • 强制加载控制器中的依赖项(只是循环遍历它们)
  • 看看this article可能还有很多关于延迟加载/延迟提取一对多关联等等的问题

想象:

// your dao
public class Foo {
    // lots of other properties
    List<Something> stuff;
    // getters and setter for stuff
}

// repository
@Transactional 
public class FooRepo {
    public Foo loadFoo(int id) {
       ...
    }
}

// Controller
public class Controller {
   public void Control() {
       sessionContext.set("foo", repo.loadFoo(1)); // transaction managed by spring
   }
   public void setFooRepo(FooRepo repo) {this.repo = repo};
}

// View
for (Something something : foo.getStuff()) {
    // Ooops transaction is closed! stuff is lazily loaded so NOT AVAILABLE
    // practical solutions:
    // - do not load lazily (Foo.hbm.xml)
    // - or force loading by getting all Somethings in the controller
}