Java 捕获重复条目异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27582757/
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
Catch duplicate entry Exception
提问by Youssef
How can i catch this Exception :
我怎样才能捕捉到这个异常:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Duplicate entry '22-85' for key 'ID_CONTACT'
采纳答案by Youssef
I use spring so we resolve it by org.springframework.dao.DataIntegrityViolationException
我使用弹簧,所以我们解决它 org.springframework.dao.DataIntegrityViolationException
try {
ao_history_repository.save(new AoHistory(..));
} catch (DataIntegrityViolationException e) {
System.out.println("history already exist");
}
But as @KevinGuancheDariasmention it:
但正如@KevinGuancheDarias提到的:
Please note that while this works. I suggest to solve the problem by issuing a findBy before the save, as this is messy, and I think it's not warranted that it will work in future versions, may even break without notification.
请注意,虽然这有效。我建议通过在 save 之前发出 findBy 来解决问题,因为这很混乱,而且我认为不能保证它可以在未来版本中工作,甚至可能会在没有通知的情况下中断。
回答by auntyellow
catch SQLIntegrityConstraintViolationException, if you are using Java 1.6+
捕获SQLIntegrityConstraintViolationException,如果您使用的是 Java 1.6+
e.g.
例如
try {
ps.executeUpdate("INSERT INTO ...");
} catch (SQLIntegrityConstraintViolationException e) {
// Duplicate entry
} catch (SQLException e) {
// Other SQL Exception
}
or
或者
try {
ps.executeUpdate("INSERT INTO ...");
} catch (SQLException e) {
if (e instanceof SQLIntegrityConstraintViolationException) {
// Duplicate entry
} else {
// Other SQL Exception
}
}
回答by SEIYA
The following code works for me:
以下代码对我有用:
try {
requete.executeUpdate();
} catch (final ConstraintViolationException e) {
}
回答by jjason
I use Spring. So catch org.springframework.dao.DuplicateKeyException
我用弹簧。所以抓住 org.springframework.dao.DuplicateKeyException
try{
...
} catch (DuplicateKeyException dke) {
...
}
回答by Levent Divilioglu
A - Log the exception in detail
A - 详细记录异常
Here is what I use to log SQL Exceptions so that I can be sure of what to catch;
这是我用来记录 SQL 异常的内容,以便我可以确定要捕获什么;
private static void handleSQLError(SQLException e) throws SQLException {
log.info("SQL Error Type : " + e.getClass().getName());
log.info("Error Message : " + e.getMessage());
log.info("Error Code : " + e.getErrorCode());
log.info("SQL State : " + e.getSQLState());
throw e;
}
Here is the sample Output;
这是示例输出;
2018 Nis 05 11:20:32,248 INFO MySQLUtil: SQL Error Type : com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException
2018 Nis 05 11:20:32,248 INFO MySQLUtil: Error Message : Duplicate entry 'test2 CAMT052' for key 'customer_file_customer_file_name_idxu'
2018 Nis 05 11:20:32,249 INFO MySQLUtil: Error Code : 1062
2018 Nis 05 11:20:32,249 INFO MySQLUtil: SQL State : 23000
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'test' for key 'customer_file_customer_file_name_idxu'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
B - Catch the Exception and check the parameters
B - 捕获异常并检查参数
To catch duplicate key Exception, we need to catch the specific class which is MySQLIntegrityConstraintViolationException
. Also the following parameter must match;
要捕获重复键异常,我们需要捕获特定的类,即MySQLIntegrityConstraintViolationException
. 此外,以下参数必须匹配;
SQL State : 23000
So I use the following block to catch duplicate entries;
所以我使用以下块来捕获重复的条目;
try {
dbUtil.persistEntry(entry);
} catch (SQLException e) {
if(e instanceof MySQLIntegrityConstraintViolationException) {
if(e.getSQLState().equals("23000")) {
if(e.getMessage().contains("Duplicate")) {
isDuplicateEntryError = true;
}
}
}
}
回答by whoami
I agree, but we've something like this in my Spring Application,:- RequestValidationException/MessageConstants are custom one's:
我同意,但我们在我的 Spring 应用程序中有这样的东西:- RequestValidationException/MessageConstants 是自定义的:
import org.springframework.dao.DuplicateKeyException;
|
|
|
catch (Exception exception) {
if(exception instanceof DuplicateKeyException) {
logger.error("exception as duplicate Name Found: " + exception.getMessage());
throw new RequestValidationException(MessageConstants.DUPLICATE_NAME_FOUND_ERROR_CD, MessageConstants.DUPLICATE_NAME_FOUND_ERROR_MSG);
}else{
logger.error("exception on update: " + exception.getMessage());
throw exception;
}
}
回答by Dennis R
Loook at Spring framework source codeLook at spring JDBC error resolve code.
查看Spring框架源码查看spring JDBC错误解决代码。
org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator#doTranslate
org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator#doTranslate
else if (Arrays.binarySearch(this.sqlErrorCodes.getDuplicateKeyCodes(), errorCode) >= 0)
{ logTranslation(task, sql, sqlEx, false); return new DuplicateKeyException(buildMessage(task, sql, sqlEx), sqlEx); }
There are multiple ways how you can hit different Exception translators:
您可以通过多种方式访问不同的异常翻译器:
- Spring load metadata/error codes from your db - one translator
- Spring fails to connect to db - another one
- Hibernate JPA may have different translator
- Spring 从您的数据库加载元数据/错误代码 - 一位翻译
- Spring 无法连接到数据库 - 另一个
- Hibernate JPA 可能有不同的翻译器
So Dublicate behavior may change from DuplicateKeyException to DataIntegrityViolationException.
因此 Dublicate 行为可能会从 DuplicateKeyException 更改为 DataIntegrityViolationException。
回答by mohsenJsh
vendorCode 2601
is for unique index constraint
violate so you can check SQLException cewndorCode by e.getErrorCode() == 2601
. sample code:
vendorCode2601
用于unique index constraint
违反,因此您可以通过 来检查 SQLException cewndorCode e.getErrorCode() == 2601
。示例代码:
try {
ao_history_repository.save(new AoHistory(..));
} catch (SQLException e) {
if (e.getErrorCode() == 2601) {
System.out.println("handle duplicate index error here!");
} else {
System.out.println("handle other error code here!");
}
}
回答by Kevin Guanche Darias
In my Spring project, the exception thrown was org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.ConstraintViolationException: could not execute statement; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
.
在我的 Spring 项目中,抛出的异常是org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.ConstraintViolationException: could not execute statement; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
.
So after debugging I had a parent JpaSystemException
with a cause PersistenceException
and that had a cause ConstraintViolationException
, this last one had the Database specific exception, but I ended up catching ConstraintViolationException
with
因此,在调试之后,我有一个JpaSystemException
有原因的父级PersistenceException
并且有一个原因ConstraintViolationException
,最后一个有数据库特定的异常,但我最终赶上ConstraintViolationException
了
public static boolean isSqlDuplicatedKey(Exception e) {
return e.getCause() != null && e.getCause().getCause() != null
&& ConstraintViolationException.class.isInstance(e.getCause().getCause());
}
// ....
try {
someRepository.save(some);
} catch (JpaSystemException e) {
if (ExceptionUtilService.isSqlDuplicatedKey(e)) {
// Do something to handle it
} else {
throw e;
}
}
Please note that while this works. I suggest to solve the problem by issuing a findBy before the save, as this is messy, and I think it's not warranted that it will work in future versions, may even break without notification.
请注意,虽然这有效。我建议通过在 save 之前发出 findBy 来解决问题,因为这很混乱,而且我认为不能保证它可以在未来版本中工作,甚至可能会在没有通知的情况下中断。