【问题标题】:EJB Transactions attribute: NOT_SUPPORTED and REQUIRES_NEWEJB 事务属性:NOT_SUPPORTED 和 REQUIRES_NEW
【发布时间】:2015-02-05 03:31:02
【问题描述】:

我目前陷入以下情况:

我正在尝试将对象 A 保存到数据库中。但是 A 由许多其他对象组成,B、C 和 B,C 由对象 D、E 组成……有很多嵌套对象,你知道我的意思。让我们把保存A的整个过程称为事务1。

在事务 1 的中间,当涉及到保存某个对象 X(通过许多链接与 A 有某种关联)时,假设是方法 saveX() 触发保存 X。在 saveX( ) 方法,业务逻辑需要对另一个对象 Y 进行另一个查询,假设该方法是 queryY()。

因此,当我们调用 queryY() 时,当它进入实际从数据库中获取所有结果的代码行时,我们遇到了异常。我们把这一刻称为 T 时间。

例外是

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: A.b -> B.

所以我的想法是,EJB容器在T时间有点想,当我们需要做一个查询时,它需要提交当前事务1并启动事务2来执行查询。显然与 A 相关的数据还没有正确保存到数据库中,所以出现了异常。

所以我们需要暂停事务 1 并在执行查询后恢复它,而不是在 T 时间提交它。我做了一些研究,发现@TransactionAttribute 可以解决这个问题。有趣的是,如果我将两者之一作为注释放在 queryY() 上,我发现以下两种解决方案都有效(没有异常发生并且应用程序正常):

@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 

我阅读了与注释相关的官方文档:http://docs.oracle.com/javaee/6/api/javax/ejb/TransactionAttributeType.html

REQUIRES_NEW 有效是有道理的。但我不明白为什么 NOT_SUPPORTED 也有效。显然我们需要另一个事务来调用 queryY() 来完成查询。而在NOT_SUPPORTED的解释中,并没有提到挂起第一个事务后会开始一个新事务。

所以我的第一个问题是,为什么 NOT_SUPPORTED 有效? 我的第二个问题是,为什么 EJB 容器认为事务 1 已结束,需要在 T 时间提交,而不是将 queryY 视为事务 1 的一部分?

提前致谢!任何帮助将不胜感激!

【问题讨论】:

    标签: java hibernate jakarta-ee jpa transactions


    【解决方案1】:

    这与事务传播无关。您应该使用一个且仅一个事务来保存所有对象。

    你得到的这个错误:

    org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: A.b -> B.
    

    是因为你试图保存 A 并且 A 和 B 之间没有级联。

    如果 A 是父级而 B 是子级(具有 FK),则将持久/合并操作从 A 级联到 B 是有意义的。否则,如果 B 是父 @OneToOne 关联,则需要先保存它。

    【讨论】:

    • 感谢您的回答,但我不能同意。添加 cascade = "CASCADE.ALL" 没有帮助。
    • org.hibernate.PropertyValueException:非空属性引用空值或瞬态值:B.a.所以 EJB 容器仍然想结束该事务并试图保存但徒劳无功
    • “如果 A 是父母,B 是孩子(有 FK)”,你的意思是 A 是拥有方(没有 mappedBy 注释)吗?
    • 所以如果我在 A(Owning side) 中添加 CASCADEType.ALL,仍然 org.hibernate.TransientObjectException: object references an unsaved transient instance - 在刷新之前保存瞬态实例:A.b -> B. 如果我在 B 中添加 CASCADEType.ALL(引用端),我有 org.hibernate.PropertyValueException: not-null property references a null or transient value: B.a.
    • 那是因为没有正确设置映射。如果您有双向关联,请确保设置双方,parent.children 集合和 child.parent 方应同步。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 2013-08-15
    • 1970-01-01
    • 2012-10-14
    相关资源
    最近更新 更多