Hibernate中StaleStateException的最佳更新策略

6
我们正在使用具有乐观锁定的 Hibernate 技术,所有实体都带有 @version 注释。
如果用户尝试保存已过期的对象,则会抛出异常,我们会收到 stalestateexception 的提示,这工作得很好。在我们的情况下,我们想向用户提供一个通知屏幕来放弃更改或覆盖数据库中的当前值。
这是一种常见的过期状态异常用例。我的问题与此用例有关。如果用户决定使用自己的更改覆盖当前数据库行,最佳策略是什么?我已查阅了 Hibernate 参考指南和不同的网站,但只是提到您必须自己捕获 stalestateexception ,然后编程处理数据的覆盖。我在想,Hibernate 是否有一些实用工具来简化此策略,如果用户决定使用他的数据进行覆盖,最简单的方法是从数据库检索实体的最后一个版本,然后将所有更改字段复制到此对象,然后将更改后的对象保存回数据库。
但我不停地在想是否有更优雅的解决方案。
2个回答

2

我认为Hibernate不会尝试帮助您解决这个问题,因为在这个领域的要求可能非常复杂和定制化。

我猜想,如果一个用户保存了一个同时被另一个用户修改的对象,您很可能不希望仅加载对象并复制所有已更改的字段并撤消其他用户的所有更改。如果两个用户都更改了同一个字段会发生什么?您可能希望向用户呈现两个版本,并要求他们决定哪个版本是正确的。有点像合并版本控制系统中的更改。

此外,如果您仅在后端合并同一实体的两个版本并将其持久化,可能会违反链接字段的UI级验证。


有时我们确实会创建一个“合并UI”。 但是在某些用例中,数据不重要到只需覆盖它,我想知道是否有默认方法来处理这种情况,或者您必须自己编写算法。 - Peter Bierman
很抱歉,我不知道。 - Alex Barnes
1
这是一个好问题。我花了相当多的时间思考如何最好地解决这种情况! - Alex Barnes

0
根据我的经验,在这种情况下引入一些自动化,我通常会使用以下技巧。重新加载实体并将其最新版本的值设置为之前保存失败的旧对象。然后我使用merge()传递我的旧对象。这样所有字段都会被覆盖,版本也是最新的,并且可以准备好保存。当然,所有相关的引用必须以同样的方式处理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接