Null @Version 列的 org.springframework.transaction.UnexpectedRollbackException

发布于 2024-09-30 12:45:13 字数 789 浏览 0 评论 0原文

我在我的应用程序中使用 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,这解决了问题。

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

I'm using Spring 3.0.4-RELEASE, JPA 2.0 with Hibernate as a provider, and JTA JOTM for transactions in my application. I've received the following error when calling entityManager.merge on my entity object:

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)    

This error came as a result of inserting data directly into the database (MySQL) through our Talend ETL job. I noticed that my @Version column in the database had NULL values and decided to set them to 0 and this resolved the issue.

Why can't the @Version column be NULL? Has anyone else come across this issue? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

喜爱纠缠 2024-10-07 12:45:13

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

如果您想完全了解这里发生的情况,请激活日志记录以准确查看导致RollbackException的原因(我怀疑“坏“SQL)。

请注意,您没有收到 OptimisticLockException,我认为 Hibernate 在某种程度上对 NULL 版本感到困惑。我并没有真正挖掘这个问题,也无法详细解释它,但似乎 Hibernate 甚至没有生成预期的合并 UPDATE 语句。

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

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

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

I've received the following error when calling entityManager.merge on my entity object

If you want to fully understand what is happening here, activate logging to see exactly what is resulting in the RollbackException (I suspect "bad" SQL).

Note that you aren't getting an OptimisticLockException, I think that Hibernate is somehow getting confused by the NULL version. I didn't really dig the problem and can't explain it in details but it seems Hibernate isn't even generating the expected UPDATE statement for the merge.

Why can't the @Version column be NULL? Has anyone else come across this issue? Thanks.

As I wrote, I can't give the exact reason but I'm tempted to answer: because that's not a value expected by Hibernate. Hibernate would start with 0 as initial value for the version column, my suggestion would be to respect Hibernate's expectation and set that as default value.

If you want to understand why setting NULL as initial value is causing troubles, you'll have to debug Hibernate's code. But honestly, this sounds like a waste of time: since you're using Hibernate, simply respect/mimic Hibernate's behavior when bypassing Hibernate's API.

娇纵 2024-10-07 12:45:13

您期望什么行为?

当您对分离对象执行合并时,如果分离实体的版本与数据库中的版本不匹配,则会引发开放式并发异常。我猜在你的情况下,这个异常被包装到 UnexpectedRollbackException 中。如果分离实体的版本为 0,则将数据库中的版本列设置为 0 可以解决此问题。

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

What behaviour do you expect?

When you perform merge on detached object, optimistic concurrency exception is thrown if version of the detached entity doesn't match version in the database. I guess in your case this exception is wrapped into UnexpectedRollbackException. If version of the detached entity is 0, setting version column in the database to 0 solves this.

The real solution would be to increment version of the entity in the database when external software changes it. It would be consistent with optimistic locking strategy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文