具有扩展持久上下文的意外分离实体

2024-01-11

我尝试使用 EXTENDED_PERSISTENT_CONTEXT 来维护多个调用之间的状态。我的理解是,托管实体不会在调用之间分离,但是在我之前抛出验证错误后,我不断收到与调用中分离实体相关的错误。状态在有状态会话 bean 中维护:

@Named(SessionFacadeBean.SEAM_NAME)
@SessionScoped
@Stateful
@LocalBean
@AccessTimeout(value = 10, unit = TimeUnit.SECONDS)
public class SessionFacadeBean implements Serializable
{
    public static final String  SEAM_NAME        = "sessionCacheBean";

    @PersistenceContext(unitName = GlobalParameters.BACKEND_CODE_PERSISTENCE_CONTEXT_NAME, type = PersistenceContextType.EXTENDED)
    private EntityManager       em;

    private ParentOne sessionData;

    public synchronized ParentOne getSessionData() {
        if(sessionData == null) {
            sessionData = new ChildTwo();
        }
        return sessionData;
    }

    public boolean getLock() {
        return true;
    }

    public void clearLock() {
    }

    // Other stuff I don’t ‘think’ is relevant.
}

(简化的)状态是使用 hibernate 存储的。它由三个类组成(一个父类和两个子类,其中一个类包含子类列表):

@XmlRootElement(name = XMLConstants.COMPONENT_ELEMENT_NAME_IN_XML)
@XmlAccessorType(XmlAccessType.NONE)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "Class", length = 50)
@Entity
public class ParentOne 
{   
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @XmlElement(name = "ID")
    private Long              iD;

    @XmlElement(name = "name")
    protected String              friendlyName          = "";
}


@XmlRootElement(name = XMLConstants.COMPONENT_ELEMENT_NAME_IN_XML)
@XmlAccessorType(XmlAccessType.NONE)
@Entity
public class ChildOne extends ParentOne
{
    public ChildOne(String name, ParentOne child) {
        super(name);
        myChild = child;
    }

    @ManyToOne(cascade = CascadeType.ALL)
    protected ParentOne myChild;   
}


@XmlRootElement(name = XMLConstants.COMPONENT_ELEMENT_NAME_IN_XML)
@XmlAccessorType(XmlAccessType.NONE)
@Entity
public class ChildTwo extends ParentOne
{
    public ChildTwo() {
            super(“common”);
    }
}

我从无状态 bean 访问有状态 bean,如下所示:

@Stateless
@LocalBean
@Path("/")
public class MyService
{
    @PersistenceContext(unitName = GlobalParameters.BACKEND_CODE_PERSISTENCE_CONTEXT_NAME)
    private EntityManager       em;

    @Inject
    private SessionFacadeBean   sessionBean;

    @POST
    @Path("/create/item")
    @ValidateRequest
    public ComponentShortSummary addItem(@Form NewItemForm itemForm)
    {       
        if(sessionBean.getLock()) {
            try {
                if(itemForm.getName().equals("INVALID") == true) {
                    throw new ConstraintViolationException("Failed", new HashSet<ConstraintViolation<?>>());
                }

                ChildOne child = new ChildOne(itemForm.getName(), sessionBean.getSessionData());
                em.persist(child);
                return null;
            }
            finally {
                sessionBean.clearLock();
            }
        } else {
            return null;
        }
    }
}

为了重现该问题,我执行以下顺序:

  • 使用有效名称调用 addItem(这会将项目保存到数据库中)。
  • 使用名称“INVALID”调用 addItem,这会引发约束异常。
  • 使用有效名称调用 addItem(这会导致线上出现分离实体错误em.persist(child).

我不明白的是我如何/为什么最终会得到分离的实体。在实际代码中,我将在修改状态之前执行一些请求/状态验证(因此我没有理由看到状态已分离)。

如果我删除对sessionBean.getLock()那么问题就消失了(对象正确地存在)。锁方法的目的本质上是序列化对会话状态的访问,但是目前getLock()方法是空的,感觉问题可能与我在抛出异常之前调用有状态bean有关。

任何人都可以解释发生了什么导致我的实体变得分离/是否有办法避免它(最好向我指出任何支持解释的文档)?

虽然可能有一些方法可以解决当前问题,在访问有状态 bean 之前执行验证,但我担心一般情况(在调用中访问有状态 bean 后抛出任何异常)。当我不希望扩展持久上下文中的实体被分离时,是否有一个可接受的策略来处理异常?


看起来这是预期的行为。谢谢斯科特·马洛 https://community.jboss.org/message/763922#763922参考 JPA 规范第 3.3.2 节。

事务回滚 对于事务范围和扩展范围 持久化上下文,事务回滚会导致所有预先存在的 托管实例和已删除实例[31] 变得分离。这 实例的状态将是此时实例的状态 事务被回滚。通常事务回滚 导致持久化上下文处于不一致的状态 回滚点。特别是版本属性的状态和 生成的状态(例如,生成的主键)可能不一致。 以前由持久性上下文管理的实例 (包括在该情况下持续存在的新实例 因此,交易)可能无法以与其他交易相同的方式重用 分离的对象 - 例如,它们在传递到合并时可能会失败 操作。[32]

因此,当事务回滚时,活动事务中涉及的实体将被分离,并且通过调用 sessionBean,我将其纳入事务中。

解决这个问题的一种方法似乎是用@AppicationException注解。这将异常标记为非致命并防止事务回滚。这种方法的详细描述如下:大卫·布莱文 http://blog.dblevins.com/2010/07/applicationexception-is-evil-sort-of.html.

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

具有扩展持久上下文的意外分离实体 的相关文章

随机推荐

  • 我可以将实体字段名称映射到 TypeORM 中的别名列名称吗?

    我正在使用 TypeORM 从 Rails 迁移到 NestJs 由于历史原因 Rails 中的表名和列名是snaked cased 我不想将这种麻烦复制到我们的 NestJs React 端 我可以在 NestJS typeorm 中创建
  • 使用新范围更新 Google 工作表“过滤器视图”

    我有一个电子表格 其中设置了各种过滤器视图 通常这很有效 但偶尔会添加新行 我必须手动更新每个过滤器视图中的范围 我尝试在线搜索解决方案 并提出了以下可能更新范围的代码 function UpdateFilterView var dataS
  • xcode4 工作区中的两个项目(#import 失败)

    我真的很难让它在 xcode 4 中工作 我有一个项目将在许多应用程序 网络 中重用 因此我创建一个工作区并添加我的两个项目 到目前为止 一切都很好 这就是失败的地方 import JSONRequest h 没有明显的原因 它自动完成头文
  • 在单个表列中存储多个位值

    我需要在数据库中存储某种一周中的日程安排 我可以在其中安排一周中的一天或多天的记录 假设它代表一个任务 我需要将其存储在一列中 以便于保存和检索 然后每天我都会选择时间表与本周的当前日期相匹配的记录 例如 获取时间表与第 7 周的日期相匹配
  • 内部矩阵尺寸必须一致

    我有一个矩阵A和一个向量x A是一个 50x30 矩阵 x是一个 1x30 向量 我想要倍增A by x 但每当我尝试z A x我收到错误Inner matrix dimensions must agree 然而 在列数相同的情况下 矩阵维
  • Elasticsearch Painless 计算嵌套元素的分数

    Note 我最初发布这个问题的方式有点不同 不值得更新 因为阅读后我学到了更多 要求 搜索文档并根据文档中的嵌套元素计算自定义分数 结构 mappings book properties title type string index no
  • 使用 gdb 中的函数调用堆栈进行导航

    在 Visual Studio 中 如果单击调用堆栈中的某个条目 则会打开编辑器并显示该函数的源代码 gdb 中可能有类似的东西吗 我在 gdb 中使用 tui 文本用户界面 是否可以让 tui 显示回溯中给定条目的源代码 如果没有 那么如
  • 如何在较新版本的 VS 中通过 UI 更改单元测试属性?

    几个月前 当我在使用 MSTest 进行单元测试时阅读有关数据源的内容时 我偶然发现了一些旧帖子 声称这只是进入属性并在 gui 上设置数据源的问题 这导致该属性与所需的参数一起自动添加到测试方法中 不过 我始终无法在属性网格上选择单元测试
  • 如何检查是否已为 VIRTUALENVWRAPPER_PYTHON=/usr/bin/python 等安装 virtualenvwrapper

    我正在遵循有关 Python 的 virtualenv 的指南 但遇到了一个小问题 Sahands MBP empty sahandzarrinkoub source usr local bin virtualenvwrapper sh u
  • 删除结构 C++ 向量中的重复项

    我有以下结构 我想将结构存储在向量中 其次我想删除 context 我究竟做错了什么 include
  • 编译器使用了错误的函数原型?

    我遇到了一个我不明白的编译问题 我将其简化了一些 以便在下面进行解释 基本上 它涉及到有 2 个不同的 getter 一个 const 和一个非常量 getter 它们返回一个带有 const 和非常量 value type 的容器 本例中
  • 通过命令行的Windows照片查看器 - 特殊功能[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想通过命令行执行在 Windows 7 和 Windows XP 下使用 Windows 照片查看器查
  • 使用 VBA 从工作簿中检索 OLEObjects 信息

    设想 我正在尝试使用 VBA 最初是 Python 但我找不到方法来执行此操作 读取所有信息或工作表 由于我必须读取的工作表具有不同的格式并且通常很混乱 因此我循环遍历工作表中的所有对象 获取它们的名称和值 检查或不检查 作为二进制文件 I
  • 为嵌套循环声明虚拟变量的更好方法是什么?

    方法 1 的优点是由于源代码中的文本字符较少 因此文件大小稍小 int i j for i 0 i lt numRows i for j 0 j lt numCols j
  • NSImage vs. CIImage vs. CGImage?

    我应该什么时候使用它们 NSImage 是一种抽象数据类型 可以表示许多不同类型的图像 以及图像的多种表示形式 当图像的实际类型对于您想要执行的操作并不重要时 它通常很有用 它也是 AppKit 在其 API NSImageView 等 中
  • Discord 机器人:如何在语音通道中播放 mp3 文件

    我为粉丝服务器制作了一个自定义的 Discord 机器人 该服务器由 Heroku 托管 因此当我不在时它可以保持在线状态 我想做的是 当有人为其发出特定命令时 让机器人播放其文件夹中的 mp3 文件 但我希望音乐在特定语音通道中播放 首先
  • iPhone + UIView。绘制矩形期间消耗大量内存。有什么策略可以减少这种情况吗?

    我的数据可视化应用程序在重绘 触发drawRect的setNeedsDisplay 期间产生大量内存消耗峰值 我目前正在重新绘制包含数据图的整个视图 该视图比设备显示屏大得多 有没有办法告诉 CoreGraphics 分配足够的内存来绘制每
  • Swift:PrepareForSegue,Swift Cast 失败

    我想在我的单元格中选择一个单元格TableViewController 单元格的文本应通过 segue 传输到 FirstViewController 的标签 我总是收到如下所示的错误 标识符是正确的 My code override fu
  • Kohana3:用于开发和生产环境的不同 .htaccess rewritebase 和 kohana base_url

    In my bootstrap php我有以下内容 if SERVER SERVER NAME localhost Kohana environment development else Kohana environment product
  • 具有扩展持久上下文的意外分离实体

    我尝试使用 EXTENDED PERSISTENT CONTEXT 来维护多个调用之间的状态 我的理解是 托管实体不会在调用之间分离 但是在我之前抛出验证错误后 我不断收到与调用中分离实体相关的错误 状态在有状态会话 bean 中维护 Na