2010-11-05 88 views
1

我使用Spring 3.0.4-RELEASE,JPA 2.0与Hibernate作为提供程序,JTA JOTM用于我的应用程序中的事务。我已经在我的实体对象调用entityManager.merge时收到以下错误:org.springframework.transaction.UnexpectedRollbackException for null @Version列

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)  

此错误之际,将数据直接写入数据库(MySQL的)通过我们的了Talend ETL作业的结果。我注意到我的数据库中的@Version列有NULL值,并决定将它们设置为0,这解决了问题。

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

回答

0

你期望什么行为?

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

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

1

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

如果你想完全了解这里发生了什么,激活日志记录,看看究竟是什么导致了RollbackException (我怀疑“坏”SQL)。

请注意,您没有得到OptimisticLockException,我认为Hibernate在某种程度上被NULL版本弄糊涂了。我没有真正解决这个问题,也不能详细解释它,但看起来Hibernate甚至没有为合并生成预期的UPDATE声明。

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

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

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