某些事务传播不适用于 Spring/Hibernate 4

2024-05-05

我正在将应用程序从 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 拒绝在没有有效事务的情况下创建会话,则很难将会话边界与会话而不是事务对齐。会话及其持久性上下文不应与开放事务绑定。


通过实施解决了这个问题CurrentSessionContext这是一个围绕 a 的包装SpringSessionContext并借用了 Spring Framework 4+ 中的一些代码更改:

public class ClassLoaderSpringSessionContext implements CurrentSessionContext {

    private final SessionFactoryImplementor sessionFactory;
    private final SpringSessionContext sessionContext;

    public ClassLoaderSpringSessionContext(final SessionFactoryImplementor sessionFactory) {
        this.sessionFactory = sessionFactory;  // This is actually some class loading logic that isn't important to this transaction problem.
        this.sessionContext = new SpringSessionContext(this.sessionFactory);
    }

    @Override
    public Session currentSession() throws HibernateException {
        try {
            return sessionContext.currentSession();
        } catch (HibernateException e) {
            if (TransactionSynchronizationManager.isSynchronizationActive()) {
                Session session = this.sessionFactory.openSession();
                if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
                    session.setFlushMode(FlushMode.MANUAL);
                }
                SessionHolder sessionHolder = new SessionHolder(session);
                TransactionSynchronizationManager
                        .registerSynchronization(new SpringSessionSynchronization(sessionHolder,
                            this.sessionFactory));
                TransactionSynchronizationManager.bindResource(this.sessionFactory, sessionHolder);
                sessionHolder.setSynchronizedWithTransaction(true);
                return session;
            } else {
                throw new HibernateException(
                        "Could not obtain transaction-synchronized Session for current thread");
            }
        }
    }
}

SpringSessionSynchronization是 Spring 4 中的一个包私有类,所以我还必须将其版本作为私有内部类拉出ClassLoaderSpringSessionContext.

希望这对其他人有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

某些事务传播不适用于 Spring/Hibernate 4 的相关文章

随机推荐

  • 从字符串中删除空格,但不在开头或结尾

    我试图从 C 中的字符串中删除空格 不是从末尾 也不是从开头 只是字符串中的多个空格 例如 hello everyone this is a test hello 和 every 之间有两个空格 从 this 到 is 有五个空格 最终我想
  • OpenCV findContours 破坏源图像

    我编写了一个在单通道空白图像中绘制圆形 直线和矩形的代码 之后 我只需找出图像中的轮廓 就可以正确获取所有轮廓 但找到轮廓后 我的源图像变得扭曲 为什么会出现这种情况 任何人都可以帮我解决这个问题 我的代码如下所示 using namesp
  • 在 JWT Laravel 中使用授权标头时获取 token_not_provided

    I read 本教程 http blog nedex io create an api server for mobile apps using laravel 5 1 我设法使它完美地工作 唯一的问题是当我从 令牌 token here
  • 如何:默认显示 video_player 插件的播放控件 (flutter-web)

    有什么方法可以默认显示视频播放器的控件吗 如果我在浏览器中右键单击视频 我就可以显示它们 所以我假设必须有一种默认显示的方法 我无法找到默认显示 video player 控件的方法 但使用了这个包 它在 Flutter web 上工作得很
  • 将数组写入文件的最佳方法? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我想避免写入数据库并使用常量 数组作为 lang 文件等 i e lang array hello gt hello world 并能够从后台编
  • 数据库镜像/Postgres流复制

    我不是 DBA 我是基于企业数据库的应用程序的主要开发人员 我目前正在指定一些新机器来升级我们现有的企业数据库 目前 我们在 DR 站点上运行带有数据库的 Postgres 8 4 该数据库通过前员工执行的一些自定义 rsync 工作定期接
  • 在 Vim 中的缩进线上按“Home”

    我有一个坏习惯 就是使用 home 键返回到行首 当我最近开始使用 vim 时 我注意到当我在缩进的行上按 home 键时 它会让我回到该行的开头 在 Notepad 我曾经使用的编辑器 中 它会让我返回到该行代码的开头 就在缩进之后 有没
  • 使用 jqGrid 的 ASP.NET MVC 路由

    我正在尝试创建一个指向 url 的链接 例如首页 详情 1在 jqGrid 列中 文档显示 showlink baseLinkUrl showAction show addParam key 2 注意 addParam 应该包含 例如 格式
  • 如何使事件 DOM 侦听器适应 Google Maps JavaScript API v3.35

    我曾经使用以下代码来捕获用户的 Enter 键事件 如果用户没有选择其中任何一个 即没有标记为 pac 的 pac item 则自动从自动完成结果 pac items 中选择第一个结果 项目选择 var input document get
  • 如何告诉 Xcode 我的 info.plist 和 .pch 文件在哪里

    我重命名了我的项目及其文件 现在 Xcode 仍在寻找旧的 info plist 文件 在哪里设置所需的 plist 和 pch 文件的位置 在我的 项目信息 窗口中 打包 下有一个 Info Plist 文件项 但它是空白的 当我尝试不同
  • MySQL - 插入后更新同一个表的触发器

    这就是我想做的 当有新的INSERT到表中ACCOUNTS 我需要更新行ACCOUNTS where pk NEW edit on通过设置status E 表示特定 旧 帐户已被编辑 DELIMITER DROP TRIGGER IF EX
  • 以编程方式添加 TabBarController

    我想以编程方式制作标签栏控制器和导航控制器 到目前为止 我的代码有效 它在底部显示了一个选项卡栏 但 OptionViewController 在第二个选项卡栏的按钮上没有说任何内容 没有标题 有趣的是 当我单击没有任何内容的按钮时 标题出
  • 使用 JNA 列出所有导出的符号名称

    如何使用 JNA 列出给定 dll 中的所有可用函数名称 JNA 允许您在运行时调用这些函数 要查看可用的内容 请使用适合该工作的工具 在 Windows 上 您有 转储箱 出口 http msdn microsoft com en us
  • R 将 data.frame 转换为 json

    我正在尝试将 data frame 转换为 json 格式 我的 data frame 具有以下结构 a lt rep c Mario Luigi each 3 b lt sample 34 57 size length a df lt d
  • jinja2.exceptions.TemplateNotFound:index.html

    我尝试使用 Flask 打开 index html run py from app import app app run debug True init py from flask import Flask app Flask name f
  • Graphviz:除了标签之外,还在节点上添加标题

    在我的 Graphviz 图中 用 DOT 编写 我希望每个节点都有一个标签 但除此之外 我还希望某些节点有一个小标题 表示该节点的一些其他唯一值 例如 如果这是一个历史图 则节点的标签可能类似于 乔治 华盛顿的诞生 标题可能为 另请参阅
  • 如何在多个端口上运行 FastAPI 应用程序?

    我有一个 FastAPI 应用程序 正在使用 Uvicorn 以编程方式在端口 30000 上运行 现在我也想在端口 8443 上运行相同的应用程序 相同的应用程序需要在这两个端口上运行 我怎样才能在Python代码中做到这一点 最小可重现
  • 如何使用链接本地 IPv6 地址访问 Web 服务器或网站?

    以下是托管 Web 服务器的计算机的 ipconfig 输出 以太网适配器本地连接 连接特定的 DNS 后缀 链路本地 IPv6 地址 fe80 f85b 4256 ee76 24a4 11 IPv4 地址 10 213 254 119 子
  • 为什么我不能执行 fmt.Sprintf("%d.%d.%d.%d", a...)?

    我正在学习 Go 但我一直坚持 Go 之旅 exercise stringer go https tour golang org methods 7 https tour golang org methods 7 这是一些代码 type I
  • 某些事务传播不适用于 Spring/Hibernate 4

    我正在将应用程序从 3 3 升级到 Hibernate 4 2 我们还使用 Spring 3 1 3 目前我们不能 不会更新 我的一些单元测试现在失败了 org hibernate HibernateException No Session