寻求一种 Spring (3.0.5) 解决方案:没有 Hibernate Session 绑定到线程,并且配置不允许在此处创建非事务性会话

发布于 2024-10-19 14:36:05 字数 697 浏览 1 评论 0 原文

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

。演示文稿(springmvc),服务(带注释的事务),数据访问(Spring / Hibernate经典sessionfactory)我的模型对象用jpa(javax.persistence.*)注释我的spring上下文配置文件在appContext.xml,appContext-service中分开。 .xml 和 appContext-dao.xml。我在 appContext-dao.xml 中定义了 Spring LocalSessionFactoryBean、Datasource 和 TransactionManager (HibernateTransactionManager),并将其放入了我的服务实现所在的位置。我已经通过控制器、服务和存储库注释包含并检测我的bean。

我很感激任何形式的帮助。

I have a Transaction problem on Spring 3.0.5. In my case I get the so-called exception "No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here"... I have tried everything so far. I can see in my log that the transactional services are detected and registered as Spring beans and I can also see in the logs that they are proxied and associated with underlying Spring transaction interceptors. (Advise) When I run my Spring MVC app my controller will call the service...... :-( but the transaction interceptors are not triggered. (??) I expect my Spring service proxy to open a session and start a transaction before calling my target service method. Since this does not happen, I get the above exception. I have been almost two days on this problem. Tried everything which I found on the internet...but in vain.

I have layered architecture: presentation (springmvc), service (transaction annotated), dataacess (Spring/Hibernate classic sessionfactory). My model objects are annotated with jpa (javax.persistence.*). My spring context config files are separated in appContext.xml, appContext-service.xml and appContext-dao.xml. I have defined my Spring LocalSessionFactoryBean, Datasource and TransactionManager (HibernateTransactionManager) in appContext-dao.xml. I have put in appContext-service.xml where my service implementations resides. In all of my config files I have included and to detect my beans through Controller, Service and Repository annotations.

I appreciate any kind of help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

丘比特射中我 2024-10-26 14:36:05

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

我建议的是一些调试。

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

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

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

It sounds like you are doing everything correctly and you know what you are doing. There's not much we can do here unless you show some configuration.

What I'd suggest is some debugging.

First: do you have Unit tests in the service layer that test the queries you are using? Perhaps you can find the error in the service layer.

Then: debug the MVC app, check the types of the injected services. Verify that they are proxies, not the original types.

  • If they are the original types, you
    have an error in your transaction
    configuration .
  • If they are proxies, step through the
    query methods and verify that the
    transaction logic is applied.
陈年往事 2024-10-26 14:36:05

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

简单的解决方案:

  • 将数据 bean 配置为急切加载
  • 强制加载控制器中的依赖项(只需循环它们)
  • 看看 这篇文章 可能还有很多关于一对多关联的延迟加载/延迟获取之类的内容

想象一下:

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

This sounds like accessing a lazily-loaded list or set of you dao after the closing of the transaction. This typically happens if you access that list in the view in stead of the controller, as your controller probably calls methods in transaction scope, and then leaves the transaction and forwards the loaded bean to the view.

Simple solutions:

  • Configure your data bean to eagerly load
  • Force loading of the dependencies in the controller (just loop through them)
  • have a look at this article ans possibly also quite a few right here on SO on lazy loading / lazy fetching of one-to-many associations and the like

Imagine:

// 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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文