Catch duplicate entry Exception

2020-05-19 07:42发布

How can i catch this Exception :

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

9条回答
家丑人穷心不美
2楼-- · 2020-05-19 08:22

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.

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

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.

查看更多
做个烂人
3楼-- · 2020-05-19 08:25

I use Spring. So catch org.springframework.dao.DuplicateKeyException

try{
    ...
} catch (DuplicateKeyException dke) {
    ...
} 
查看更多
一纸荒年 Trace。
4楼-- · 2020-05-19 08:32

Loook at Spring framework source code Look at spring JDBC error resolve code.

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

So Dublicate behavior may change from DuplicateKeyException to DataIntegrityViolationException.

查看更多
登录 后发表回答