java - 如何使用 Hibernate 模仿 upsert 行为?

标签 java hibernate orm upsert

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

我想我总是可以尝试插入,如果我发现异常则进行更新,但这似乎很老套而且不是最理想的。有没有关于以干净的方式执行此操作的提示?

最佳答案

We are using MySQL, which provides an INSERT ... ON DUPLICATE KEY UPDATE syntax, but I'm not sure how or if Hibernate can be made to make use of it?

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

I suppose I could always try the insert, and if I catch an exception do an update, but that seems hacky and suboptimal. Any tips on a clean way to do this?

另一种选择是:

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

但是除非您在此过程中锁定整个 表,否则您可能会在多线程和分布式环境中面临一些竞争条件,并且第 3 步可能会失败。想象一下两个并发线程:

线程 1:

  • 开始翻译
  • 对键执行选择
  • 没有找到记录
  • 创造记录
  • promise

线程 2:

  • 开始翻译
  • 对同一个键执行选择
  • 没有找到记录
  • 创造记录
  • 提交(失败!因为线程 1 速度更快并且现在存在具有相同唯一键的记录)

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

关于java - 如何使用 Hibernate 模仿 upsert 行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3671481/

相关文章:

java - @Transient 在 hibernate 状态下不工作

Django 查询集将空值与空 OuterRef 匹配

java - @Implementation 如何使用?

javascript - Sequelize associations - 请改用promise-style

java - 为什么我的 View 数组返回 null?

java - 如何将 Swing JFrame 配置为 Spring bean?

java - 如何在 Netbeans (Ubuntu) 中包含 Weka API javadoc

java - 实现 Hibernate Search 后 Hibernate Criteria 弃用警告

java - Hibernate JUnit 测试持久化 vs. jsf live 持久化

java - 有一个通用的 Spring ApplicationContextProvider 供所有 spring 管理的 bean 和其他 bean 使用