捕获重复条目异常

时间:2014-12-20 17:48:04

标签: java mysql hibernate jpa sqlexception

我怎样才能抓住这个例外:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 
                                      Duplicate entry '22-85' for key 'ID_CONTACT'

9 个答案:

答案 0 :(得分:22)

我使用spring,所以我们通过org.springframework.dao.DataIntegrityViolationException

解决它
    try {
        ao_history_repository.save(new AoHistory(..));
    }
    catch (DataIntegrityViolationException e) {
        System.out.println("history already exist");
    }

答案 1 :(得分:8)

catch SQLIntegrityConstraintViolationException ,如果您使用的是Java 1.6 +

e.g。

try {
    ps.executeUpdate("INSERT INTO ...");
} catch (SQLIntegrityConstraintViolationException e) {
    // Duplicate entry
} catch (SQLException e) {
    // Other SQL Exception
}

try {
    ps.executeUpdate("INSERT INTO ...");
} catch (SQLException e) {
    if (e instanceof SQLIntegrityConstraintViolationException) {
        // Duplicate entry
    } else {
        // Other SQL Exception
    }
}

答案 2 :(得分:1)

A - 详细记录异常

以下是我用来记录SQL Exceptions的内容,以便我可以确定要捕获的内容;

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 - 捕获异常并检查参数

要捕获重复键Exception,我们需要捕获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;
            }
        }
    }
}

答案 3 :(得分:1)

vendorCode 2601是针对unique index constraint的违反,因此您可以通过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!");
    }
}

答案 4 :(得分:1)

在我的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

因此,在调试之后,我有一个原因为JpaSystemException的父级PersistenceException,而原因为ConstraintViolationException,这最后一个有特定于数据库的异常,但是我最终捕获了{{ 1}}与

ConstraintViolationException

请注意,尽管这可行。 我建议通过在保存之前发出findBy来解决问题,因为这很麻烦,而且我认为不保证它可以在将来的版本中使用,甚至可能在没有通知的情况下中断。

答案 5 :(得分:0)

以下代码适用于我:

try {
    requete.executeUpdate();
} catch (final ConstraintViolationException e) {

}

答案 6 :(得分:0)

我同意,但是我们的Spring Application中有这样的内容: 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;
    }
 }

答案 7 :(得分:0)

查看Spring框架source code 查看spring JDBC错误解决代码。

  

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); }

您可以通过多种方式来使用不同的异常翻译器:

  • 从数据库中弹簧加载元数据/错误代码-一个翻译器
  • Spring无法连接到数据库-另一个
  • 休眠的JPA可能具有不同的翻译器

因此Dublicate行为可能会从DuplicateKeyException更改为DataIntegrityViolationException。

答案 8 :(得分:-2)

这个答案来自this

can't get response status code with JavaScript fetch

        fetch(`${baseUrl}api/user/login`, {
            withCredentials: true,
            headers: myHeaders
        })
            .then(function (response) {
                if (response.status !== 200) {
                    //throw the error from here to next promise if response doesn't success.
                    throw new Error(response.status);
                } else {
                    //if sucess, the response send to the next promise.
                    return response.json();
                }
            })
            .then(function (json) {
                //get your success data here
                dispatch(setLoginInfo(json))
            }).catch(err => {
               //you can catch the error code here now 
               console.log(err);
           });