【发布时间】: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