1

我正在使用 Spring 3.0.4-RELEASE、JPA 2.0 和 Hibernate 作为提供者,以及 JTA JOTM 用于我的应用程序中的事务。entityManager.merge调用我的实体对象时收到以下错误:

org.objectweb.jotm.SubCoordinator commit_one_phase
INFO: Rollback during beforeCompletion in SubCoordinator.commit_one_phase
org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException 
      at
 org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1012)    

此错误是由于通过我们的 Talend ETL 作业将数据直接插入数据库 (MySQL) 造成的。我注意到我@Version在数据库中的列有NULL值,并决定将它们设置为 0,这解决了问题。

为什么不能@VersionNULL?有没有其他人遇到过这个问题?谢谢。

4

2 回答 2

1

在我的实体对象上调用 entityManager.merge 时收到以下错误

如果您想完全了解此处发生的情况,请激活日志记录以查看究竟是什么导致了RollbackException(我怀疑“坏”SQL)。

请注意,您没有得到OptimisticLockException,我认为 Hibernate 不知何故被该NULL版本弄糊涂了。我并没有真正挖掘问题,也无法详细解释它,但似乎 Hibernate 甚至没有UPDATE为合并生成预期的语句。

为什么@Version 列不能为NULL?有没有其他人遇到过这个问题?谢谢。

正如我所写,我无法给出确切的原因,但我很想回答:因为这不是 Hibernate 所期望的值。Hibernate 将从0version 列的初始值开始,我的建议是尊重 Hibernate 的期望并将其设置为默认值。

如果您想了解为什么设置NULL为初始值会导致麻烦,您必须调试 Hibernate 的代码。但老实说,这听起来像是在浪费时间:因为您使用的是 Hibernate,所以在绕过 Hibernate 的 API 时只需尊重/模仿 Hibernate 的行为。

于 2010-11-06T22:43:24.490 回答
0

你期望什么行为?

在分离对象上执行merge时,如果分离实体的版本与数据库中的版本不匹配,则会引发乐观并发异常。我想在你的情况下这个异常被包装到UnexpectedRollbackException. 如果分离实体的版本是0,在数据库中设置版本列来0解决这个问题。

真正的解决方案是在外部软件更改实体时增加数据库中实体的版本。这将与乐观锁定策略一致。

于 2010-11-05T23:20:42.717 回答