如何用JPA会话实现并发GetOrCreate



我需要在spring-jpa(hibernate)驱动的web应用程序中实现一个实体的GetOrCreate(我称之为ensureExists)
我有一个分层的应用程序(WS-Services/DAL/Datastore),我想在服务层(spring驱动)中实现此功能
基本思想是:

  1. 查找实体
  2. 如果找到,请将其退回
  3. 否则,将实体持久化
  4. 如果一切正常,请退货
  5. 如果发生了唯一约束冲突,请尝试再次查找实体并返回它

问题产生于这样一个事实,即一旦抛出异常,hibernate会话就应该关闭并重新打开(根据session的文档),这使得步骤5无效,但我仍然希望将此逻辑封装在服务层中(而不是将其驻留在DAL或WS中)。

我很想听听关于如何解决这个问题的建议,我有一个想法,但在发布之前我想听听一些意见,以免答案向它倾斜。

提前感谢

更新
我想到的解决方案如下:
将阶段3重构为包范围的服务,该服务具有单个ensureExists方法(具有泛型),该方法接受该类型的Dao和实体,并具有REQUIRES_NEW的传播。此方法将尝试持久化,如果失败,当然会抛出一个异常,该异常将在原始服务中捕获,并且如果抛出了该异常,则会尝试持久化
我很想得到一些关于如何以其他方式实现这一点的反馈
如果几天后没有人会提出其他建议,我会把它作为一个答案和一个代码示例发布并接受它。

要查找实体,可以使用标准api+反射来填充所有重要属性并按示例对象进行搜索。要解决并发问题,请考虑悲观锁定。当您加载时,只需锁定该对象,并在所有事务完成后释放该锁定。不确定这是否是关于表演的最佳选择,但你永远不应该在这里遇到例外。

最新更新