Java 休眠约束 ConstraintViolationException。有没有一种简单的方法可以忽略重复的条目?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2893969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate constraint ConstraintViolationException. Is there an easy way to ignore duplicate entries?
提问by luxerama
Basically I've got the below schema and I'm inserting records if they don't exists. However when it comes to inserting a duplicate it throws and error as I would expect. My question is whether there is an easy way to make Hibernate to just ignore inserts which would in effect insert duplicates?
基本上我有以下模式,如果记录不存在,我将插入记录。但是,当涉及到插入重复项时,它会按照我的预期抛出并出错。我的问题是是否有一种简单的方法可以让 Hibernate 忽略实际上会插入重复项的插入?
CREATE TABLE IF NOT EXISTS `method` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
SEVERE: Duplicate entry 'GET' for key 'name'
Exception in thread "pool-11-thread-4" org.hibernate.exception.ConstraintViolationException: could not insert:
采纳答案by Pascal Thivent
My question is whether there is an easy way to make Hibernate to just ignore inserts which would in effect insert duplicates?
我的问题是是否有一种简单的方法可以让 Hibernate 忽略实际上会插入重复项的插入?
How could Hibernate possibly know that a record has a non unique value without actually inserting the record?
Hibernate 如何在不实际插入记录的情况下知道记录具有非唯一值?
If you are doing batch inserts and don't want to rollback the whole transaction and discard the session in case of a ConstraintViolationException(that's what you should do in theory after an exception, see this threadand this previous answer), my suggestion would be to use the StatelessSessionAPI and to catch the ConstraintViolationException.
如果您正在执行批量插入并且不想回滚整个事务并丢弃会话ConstraintViolationException(这是您理论上应该在异常之后做的事情,请参阅此线程和上一个答案),我的建议是使用StatelessSessionAPI 并捕获ConstraintViolationException.
回答by Lars Andren
Just like Pascal said, Hibernate won't know if it is a duplicate until it has actually been insrted.
正如 Pascal 所说,Hibernate 不会知道它是否是重复的,直到它被实际插入。
I encountered a similar situation before; several threads were doing insertions to the DB, but some of those would be duplicates. All I did was to catch and gracefully recover when one of those exceptions were thrown.
我之前也遇到过类似的情况;几个线程正在对数据库进行插入,但其中一些将是重复的。我所做的只是在抛出这些异常之一时捕获并优雅地恢复。
回答by Dean Povey
Hibernate can't do this. You can however do it yourself. Essentially there are two options:
休眠无法做到这一点。不过你可以自己做。基本上有两种选择:
- Check for duplicates before insert; or
- Catch the ConstraintViolationException and then make sure that the violation is due to a duplicate (since there can be other reasons, like null fields).
- 插入前检查重复项;或者
- 捕获 ConstraintViolationException,然后确保违规是由于重复造成的(因为可能有其他原因,例如空字段)。
The former has the disadvantage that you are checking for duplicates on every insert when the likelihood of there actually being a duplicate may be low. The latter will be faster for usual case where no duplicates occur, but has the disadvantage that you need to check for duplicates after the face. When a ConstraintViolationException is thrown it invalidates the current session; this means you will need to flush before doing a search of a duplicate.
前者的缺点是您在每次插入时检查重复项,而实际上存在重复项的可能性可能很低。对于没有重复发生的通常情况,后者会更快,但缺点是您需要在人脸之后检查重复。当抛出 ConstraintViolationException 时,它会使当前会话无效;这意味着您需要在搜索重复项之前刷新。
Checking for duplicates before insert is probably the cleanest approach unless there is a major performance problem that you need to worry about. Make sure you do the lookup and insert in a transaction to ensure that someone doesn't add a duplicate between the lookup and insert, otherwise you will get a ConstraintViolationException.
在插入之前检查重复项可能是最干净的方法,除非您需要担心主要的性能问题。确保在事务中进行查找和插入,以确保有人不会在查找和插入之间添加重复项,否则您将收到 ConstraintViolationException。
回答by agas
Instead of using createQuery() in hibernate, use createSQLQuery() and try a query like "REPLACE INTO method (id) VALUES (123);"
不要在休眠中使用 createQuery(),而是使用 createSQLQuery() 并尝试像“REPLACE INTO method (id) VALUES (123);”这样的查询。
回答by sendon1982
You can try catch the exception org.hibernate.exception.ConstraintViolationExceptionand swallow the exception in your code
您可以尝试捕获异常org.hibernate.exception.ConstraintViolationException并在代码中吞下异常
For example:
例如:
try {
sessionFactory.getCurrentSession().saveOrUpdate(entity);
} catch (ConstraintViolationException e) {
// Ignore the exception here by doing nothing
}
回答by Ar maj
even if you catch the exception, there may be other problems
即使捕获异常,也可能存在其他问题
try{
session.save(O);
session.getTransaction().commit();
}catch (HibernateException e) {
System.out.println("you are carched ¤#%SD¤") ;
}
回答by vishva
You can use @SqlInsert annotation on your entity, to change the sql hibernate uses to make insertion in Database, hibernate currently must be using this statement
您可以在您的实体上使用@SqlInsert 批注,以更改 sql hibernate 用于在数据库中进行插入,目前 hibernate 必须使用此语句
insert into method(name, id) values (?,?)
If you are using mysql, you can use the @SqlInsert statement to change the insert sql by using insert ignore mysql statement
如果你使用的是mysql,你可以使用@SqlInsert语句通过insert ignore mysql语句来改变insert sql
@SQLInsert(sql = "insert ignore into method(name, id) values (?,?)")
However you should get the insert sqls by enabling show sql mode in hibernate, since the order of the columns is generated via some logic, and their docs suggest this way.
但是,您应该通过在休眠中启用 show sql 模式来获取插入 sql,因为列的顺序是通过某些逻辑生成的,并且他们的文档建议采用这种方式。

