我正在寻找一种方法来保存或更新记录,根据表的唯一键(由多个列组成)。
我希望实现INSERT ... ON DUPLICATE KEY UPDATE
使用的相同功能 - 意味着盲目保存记录,让DB / Hibernate插入新的记录,或者如果唯一密钥已经存在则更新现有记录。
我知道我可以使用@SQLInsert( sql="INSERT INTO .. ON DUPLICATE KEY UPDATE")
,但我希望不要编写自己的SQL并让Hibernate完成这项工作。 (我假设它会做得更好 - 否则为什么要使用Hibernate?)
答案 0 :(得分:2)
这对我来说听起来不是一个干净的方法。最好首先查看具有给定密钥的实体是否存在。如果是,请更新并保存,如果没有创建新的。
修改
或者考虑一下merge()是否正在寻找:
< http://docs.jboss.org/hibernate/core/3.3/reference/en/html/objectstate.html
答案 1 :(得分:2)
当您尝试插入破坏约束的行(包括唯一约束)时,Hibernate可能会抛出ConstraintViolationException
。如果你没有得到那个异常,你可能会得到一些其他一般的Hibernate异常 - 它取决于Hibernate的版本以及Hibernate将MySQL异常映射到你的数据库版本和类型中的Hibernate异常的能力使用(我还没有对所有内容进行过测试)。
您只会在调用flush()
后获得异常,因此您应该确保它也在您的try-catch块中。
我会小心实现解决方案,您首先检查该行是否存在。如果多个会话同时更新表,则可能会出现竞争条件。两个进程几乎同时读取该行以查看它是否存在;他们都发现它不存在,然后他们都试图创建一个新行。一个人将失败取决于谁赢得比赛。
更好的解决方案是首先尝试插入,如果失败,则认为它已经存在。但是,一旦有异常,您将不得不回滚,因此这将限制您使用此方法的方式。
答案 2 :(得分:0)
您可以使用Session类中的saveOrUpdate()。