如何使用Hibernate模仿upsert行为?

2022-09-04 03:38:48

我正在编写一个应用程序,该应用程序将实体从第三方数据源同步到我们自己的架构中,中间有一个转换/映射步骤。我正在使用Hibernate来表示和持久化我们自己的架构中的实体。我遇到的一个问题是,我的一个表上有一个唯一的多列键。我希望看到的行为类似于更新:当Hibernate去持久化一个实体并检测到唯一的约束冲突时,它会进行更新。我们正在使用MySQL,它提供了一个INSERT ...关于重复密钥更新语法,但我不确定如何或是否可以使Hibernate使用它?

我想我可以随时尝试插入,如果我发现异常,请进行更新,但这似乎很笨拙且不理想。关于清洁方法的任何提示?


答案 1

我们正在使用MySQL,它提供了一个INSERT ...关于重复密钥更新语法,但我不确定如何或是否可以使Hibernate使用它?

看起来有人通过覆盖Hibernate用于此实体的语句来做到这一点。如果您不介意不具有可移植性(并且可能使用存储过程),请看一看。sql-insert

我想我可以随时尝试插入,如果我发现异常,请进行更新,但这似乎很笨拙且不理想。关于清洁方法的任何提示?

另一种选择是:

  1. 对唯一键执行选择
  2. 如果找到记录,请更新它
  3. 如果找不到记录,请创建它

但是,除非在此过程中锁定整个表,否则在多线程和分布式环境中可能会遇到一些争用情况,步骤 #3 可能会失败。想象一下两个并发线程:

线程 1:

  • 开始反式
  • 对键执行选择
  • 未找到记录
  • 创建记录

线程 2:

  • 开始反式
  • 对同一键执行选择
  • 未找到记录
  • 创建记录
  • commit (FAIL!因为线程 1 速度更快,并且现在存在具有相同唯一键的记录)

因此,无论如何,您都必须实现某种重试机制(锁定整个表不是IMO的好选择)。


答案 2

可以通过“选择...更新”


推荐