如何使用 Hibernate 模拟 upsert 行为?
我正在编写一个应用程序,将第三方数据源的实体同步到我们自己的架构中,中间有一个转换/映射步骤。我使用 Hibernate 来表示并持久保存我们自己的模式中的实体。我遇到的一个问题是我的一个表上有一个唯一的多列键。我希望看到的行为类似于更新插入:当 Hibernate 去持久化一个实体并检测到唯一约束违规时,它会进行更新。我们正在使用 MySQL,它提供了 INSERT ... ON DUPLICATE KEY UPDATE 语法,但我不确定 Hibernate 如何或是否可以使用它?
我想我总是可以尝试插入,如果我发现异常则进行更新,但这似乎很糟糕并且不是最理想的。有什么干净的方法可以做到这一点吗?
I'm writing an application that sync's entities from a third party datasource into our own schema, with a transformation/mapping step in between. I'm using Hibernate to represent and persist the entities in our own schema. A problem I'm running into is that I have a unique multi-column key on one of my tables. The behavior I would like to see is analogous to an upsert: when Hibernate goes to persist an entity and detects a unique constraint violation, it does an update instead. 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?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看起来有人通过覆盖
sql-insert
做到了这一点 code> Hibernate 为此实体使用的语句。如果您不介意不可移植(并且可能使用存储过程),请看一下。
另一种选择是:
但除非您在执行期间锁定整个表在此过程中,您可能会在多线程和分布式环境中面临一些竞争条件,并且步骤 #3 可能会失败。想象两个并发线程:
线程 1:
线程 2:
因此无论如何您都必须实现某种重试机制(在我看来,锁定整个表不是一个好的选择)。
It looks like someone did it by overriding the
sql-insert
statement used by Hibernate for this entity. If you don't mind not being portable (and probably using a stored procedure), have a look.Another option would be to:
But unless you lock the whole table(s) during the process, you can face some race condition in a multi-threaded and distributed environment and step #3 can potentially fail. Imagine two concurrent threads:
Thread 1:
Thread 2:
So you would have to implement some kind of retry mechanism anyway (locking the whole table(s) is not a good option IMO).
可以通过“选择...进行更新”来避免竞争条件
The race condition can be avoided by "select ... for update"