Hibernate (JPA):当多个对象被修改和提交时如何处理 StaleObjectStateException
考虑以下场景: 一项数据库事务涉及不同表中的多个行并进行版本控制。
例如: 商店列表和产品。商店列表可能包含产品(及其在商店列表中的数量),并且产品具有当前库存。
当我插入或编辑 shopList 时,我希望更新 shopList 中这些产品的库存以保持库存一致。
为此,我打开一个事务,插入/更新 shopList,更新每个产品的库存(应用增量),然后提交事务。到现在为止还没什么大不了的。
然而,其他用户可能已经更新了一个或多个共同的产品。或者甚至更新了 shopList 本身。在这两种情况下,我在提交事务时都会收到 StaleObjectStateException。
问题是:有没有办法确定哪个表导致了 StaleObjectStateException?
如果产品导致异常,我可以从数据库刷新所有涉及的产品,然后重新应用库存增量。那很好。 如果 shopList 导致异常,最好将问题报告给用户,以便他可以重新开始。
非常感谢您的帮助。
Consider the scenario:
A Db transaction envolving more than one row from different tables with versioning.
For example:
A shopLists and products. Where a shopList may contain products (with their amount in the shoplist) and products have their current stock.
When I insert ou edit a shopList, I want the stock of those products in the shopList to be updated to keep the stock consistant.
To do that, I open a transaction, insert/update the shopList, update the stocks for each product (apply delta) and then commit the transaction. No big deal up to now.
However, other user may have updated one or more products in common. Or even updated the shopList itself. In both cases, I would get a StaleObjectStateException when commiting the transaction.
Question is: Is there a way to determine which table caused the StaleObjectStateException?
In case the product caused the exception, I could refresh all envolved products from the DB and then reapply the stock deltas. And that's fine.
In case the shopList caused the exception, it would be better to simply report the issue to the user so he could start over again.
Thanks very much for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我知道怎么做了。
首先要做的事情是:
JPA(或 hibernate 本身)将 org.hibernate.StaleObjectStateException 异常包装为 javax.persistence.OptimisticLockException。
因此,如果您想捕获正确的异常,请使用 OptimisticLockException。
第二:
只有在提交之前调用 EntityManager 的方法 Flush 时,hibernate 才会抛出 OptimisticLockException。如果你直接调用 Commit,你会得到另一个异常(我忘了是哪个)。考虑到几乎每个人都会捕获提交方法发出的异常并进行事务回滚,您将得到回滚相关的异常(再次记不清是哪个异常)。
第三次也是最后一次回答我原来的问题:
您只需从 OptimisticLockException 实例调用 getEntity 方法即可获取版本控制错误的来源。这将为您提供与此相关的任何您需要的东西。
感谢所有路过这里的人。
如有任何疑问,请提出,我很乐意提供帮助。
I found out how.
First things first:
the JPA (or the hibernate itself) wraps the org.hibernate.StaleObjectStateException exception as javax.persistence.OptimisticLockException.
So, if you want to catch the right exception, go for OptimisticLockException.
Second:
The hibernate will only throw the OptimisticLockException when you call EntityManager's method Flush before commit. If you call Commit directly you will get another exception instead (I've forgot which). Considering almost everyone catches those exceptions issued by the commit method and go for a transaction rollback, you'll get a Rollback's related exception (can't remember which once again).
Third and finaly answering my original question:
You just have to call the getEntity method from the OptimisticLockException instance to get the origin of the Versioning error. That's going to provide you anything you need related to that.
Thanks for all of those who passed by here.
Any questions regarding that, just ask and I'll be glad to help.