如何使用Hibernate模仿upsert行为?

时间:2010-09-08 20:08:23

标签: java hibernate orm upsert

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

我想我总是可以尝试插入,如果我捕获异常做一次更新,但这看起来很麻烦且不是最理想的。有关干净方法的任何提示吗?

2 个答案:

答案 0 :(得分:6)

  

我们正在使用MySQL,它提供了INSERT ... ON DUPLICATE KEY UPDATE语法,但我不确定如何或者是否可以使用Hibernate来使用它?

通过覆盖Hibernate为此实体使用的sql-insert语句,看起来像某人did it。如果您不介意不可移植(并且可能使用存储过程),请查看。

  

我想我总是可以尝试插入,如果我捕获异常做一次更新,但这看起来很麻烦且不是最理想的。有关干净方法的任何提示吗?

另一种选择是:

  1. 对唯一键执行选择
  2. 如果您找到记录,请更新
  3. 如果您没有找到记录,请创建
  4. 但除非您在此过程中锁定整个表,否则您可能会遇到多线程和分布式环境中的某些竞争条件,并且步骤#3可能会失败。想象一下两个并发线程:

    主题1:

    • 开始转型
    • 对密钥执行选择
    • 未找到记录
    • 创建记录
    • 提交

    主题2:

    • 开始转型
    • 对同一个键执行选择
    • 未找到记录
    • 创建记录
    • 提交(失败!,因为线程1更快,现在存在具有相同唯一键的记录)

    所以你必须实现某种重试机制(锁定整个表格不是IMO的好选择)。

答案 1 :(得分:3)

“选择...更新”

可以避免竞争条件