Java 捕获重复条目异常
如何捕获此异常:Java 捕获重复条目异常,java,mysql,hibernate,jpa,sqlexception,Java,Mysql,Hibernate,Jpa,Sqlexception,如何捕获此异常: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '22-85' for key 'ID_CONTACT' 如果您使用的是Java 1.6,请捕获SQLIntegrityConstraintViolationException+ e、 g 或 我使用spring,所以
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Duplicate entry '22-85' for key 'ID_CONTACT'
如果您使用的是Java 1.6,请捕获SQLIntegrityConstraintViolationException+ e、 g 或
我使用spring,所以我们通过
org.springframework.dao.DataIntegrityViolationException
try {
ao_history_repository.save(new AoHistory(..));
} catch (DataIntegrityViolationException e) {
System.out.println("history already exist");
}
但正如我提到的:
请注意,虽然这是可行的我建议通过以下方式解决问题:
在保存之前发出findBy,因为这很混乱,而且我认为
不保证它在将来的版本中工作,甚至可能会中断
没有通知
以下代码适用于我:
try {
requete.executeUpdate();
} catch (final ConstraintViolationException e) {
}
我用弹簧。
所以捕获org.springframework.dao.DuplicateKeyException
try{
...
} catch (DuplicateKeyException dke) {
...
}
A-详细记录异常
下面是我用来记录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;
}
这是示例输出
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-捕获异常并检查参数
要捕获重复密钥异常,我们需要捕获特定类,该类是MySQLIntegrityConstraintViolationException
。此外,以下参数必须匹配
SQL State : 23000
因此,我使用下面的块捕获重复的条目
try {
dbUtil.persistEntry(entry);
} catch (SQLException e) {
if(e instanceof MySQLIntegrityConstraintViolationException) {
if(e.getSQLState().equals("23000")) {
if(e.getMessage().contains("Duplicate")) {
isDuplicateEntryError = true;
}
}
}
}
我同意,但我的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;
}
}
Loook在Spring框架中的应用
查看SpringJDBC错误解决代码
org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator#doTranslate
有多种方法可以命中不同的异常转换器:
- Spring从db-one转换器加载元数据/错误代码
- Spring无法连接到db-另一个
- Hibernate JPA可能有不同的转换器
因此,Duplicate行为可能会从DuplicateKeyException更改为DataIntegrityViolationException vendorCode
2601
用于唯一索引约束
违犯,因此您可以通过e.getErrorCode()==2601
检查SQLException cewndorCode。示例代码:
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!");
}
}
在我的Spring项目中,引发的异常是
org.springframework.orm.jpa.JpaSystemException:org.hibernate.exception.ConstraintViolationException:cannotexecute语句;嵌套异常为javax.persistence.PersistenceException:org.hibernate.exception.ConstraintViolationException:无法执行语句
因此,在调试之后,我有一个父级JpaSystemException
,它有一个原因PersistenceException
,并且它有一个原因ConstraintViolationException
,最后一个异常是特定于数据库的异常,但我最终捕获了ConstraintViolationException
publicstaticboolearnissqlduplicatedkey(异常e){
返回e.getCause()!=null和&e.getCause().getCause()!=null
&&ConstraintViolationException.class.isInstance(例如getCause().getCause());
}
// ....
试一试{
someRepository.save(some);
}捕获(JpaSystemException e){
if(例外TilService.isSqlDuplicatedKey(e)){
//做点什么来处理它
}否则{
投掷e;
}
}
请注意,虽然这是可行的我建议在保存之前发出findBy来解决这个问题,因为这很混乱,而且我认为不保证它在未来版本中可以工作,甚至可能在没有通知的情况下中断。这个答案来自于此
fetch(`${baseUrl}api/user/login`{
事实上,
标题:myHeaders
})
.然后(功能(响应){
如果(response.status!==200){
//如果响应不成功,则将错误从这里抛出到下一个承诺。
抛出新错误(response.status);
}否则{
//如果成功,响应将发送到下一个承诺。
返回response.json();
}
})
.then(函数(json){
//在这里获取您的成功数据
调度(setLoginInfo(json))
}).catch(错误=>{
//您现在可以在这里捕获错误代码
控制台日志(err);
});
最好解决导致此异常的问题。这不是问题,但对于web应用程序,用户可以更改http请求参数,我希望确保每件事都能正常工作,因此我希望添加此层安全性。但从stacktrace中可以看出,在插入过程中,您违反了约束,这样更好先验证数据,然后再将其发送到数据库。如果你真的想,你显然可以捕获异常,但我更喜欢一个更干净的解决方案最干净的解决方案是将用户重定向到某个一般的web错误页面,该页面不显示异常跟踪(显然),但会提醒系统所有者。比试图处理这些特殊攻击案例要好得多……但您如何知道它是重复条目异常呢。异常表示约束冲突。如果它是另一个约束呢?SQLIntegrityConstraintViolationException的不可访问的catch块。此异常从不从try语句体抛出
@Youssef,mysql连接器java的版本是什么?您尝试更新的SQL是什么?需要捕获SQLException。然后可以检测它是否为SQLIntegrityConstraintViolationException。请注意,MySQLIntegrityConstraintViolationException是SQLIntegrityConstraintViolationException的一种类型。如果有人(以我的身份)来到这里,SQL状态不是重复条目错误的直接指示器。如果您查看MariaDB的官方错误文档(它们有共享错误;),您将看到导致该状态的多个错误。这里更重要的信息是错误代码,因为它直接映射到错误。(在某些情况下,您必须检查多个代码,例如,我发现死锁可能返回1213和1205)。TLDR:最好检查错误代码而不是sql s
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;
}
}
else if (Arrays.binarySearch(this.sqlErrorCodes.getDuplicateKeyCodes(), errorCode) >= 0)
{ logTranslation(task, sql, sqlEx, false); return new DuplicateKeyException(buildMessage(task, sql, sqlEx), sqlEx); }
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!");
}
}