【问题标题】:Seeking a Spring (3.0.5) Solution for: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here寻求Spring(3.0.5)解决方案:没有Hibernate Session绑定到线程,并且配置不允许在此处创建非事务性会话
【发布时间】:2011-07-05 08:20:25
【问题描述】:

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

我有分层架构:表示(springmvc)、服务(事务注释)、数据访问(Spring/Hibernate 经典会话工厂)。我的模型对象用 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。

感谢任何形式的帮助。

【问题讨论】:

  • 你有没有在 spring 中将事务管理器注入到 tx:annotation 中。像这样

标签: java hibernate spring transactions spring-aop


【解决方案1】:

听起来你做的一切都是正确的,你知道自己在做什么。除非您显示一些配置,否则我们在这里无能为力。

我建议进行一些调试。

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

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

  • 如果它们是原始类型,您 您的交易有误 配置。
  • 如果它们是代理,请单步执行 查询方法并验证 应用事务逻辑。

【讨论】:

    【解决方案2】:

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

    简单的解决方案:

    • 配置您的数据 bean 以快速加载
    • 在控制器中强制加载依赖项(只需循环它们)
    • 看看this article 和可能还有很多关于延迟加载/延迟获取一对多关联等的SO

    想象一下:

    // 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
    }
    

    【讨论】:

    • 您好 Extraneon,我相信我的问题与您描述的场景无关。问题始于会话的开始。那时我的程序终止。它永远没有机会访问数据库。因此,我认为这不是延迟加载问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多