@SuppressWarnings("serial") @Test public void customTranslateMethodTranslation() { final String TASK = "TASK"; final String SQL = "SQL SELECT *"; final DataAccessException customDex = new DataAccessException("") {}; final SQLException badSqlEx = new SQLException("", "", 1); SQLException intVioEx = new SQLException("", "", 6); SQLErrorCodeSQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator() { @Override @Nullable protected DataAccessException customTranslate(String task, @Nullable String sql, SQLException sqlex) { assertEquals(TASK, task); assertEquals(SQL, sql); return (sqlex == badSqlEx) ? customDex : null; } }; sext.setSqlErrorCodes(ERROR_CODES); // Shouldn't custom translate this assertEquals(customDex, sext.translate(TASK, SQL, badSqlEx)); DataIntegrityViolationException diex = (DataIntegrityViolationException) sext.translate(TASK, SQL, intVioEx); assertEquals(intVioEx, diex.getCause()); }
@Test public void customExceptionTranslation() { final String TASK = "TASK"; final String SQL = "SQL SELECT *"; final SQLErrorCodes customErrorCodes = new SQLErrorCodes(); final CustomSQLErrorCodesTranslation customTranslation = new CustomSQLErrorCodesTranslation(); customErrorCodes.setBadSqlGrammarCodes(new String[] {"1", "2"}); customErrorCodes.setDataIntegrityViolationCodes(new String[] {"3", "4"}); customTranslation.setErrorCodes(new String[] {"1"}); customTranslation.setExceptionClass(CustomErrorCodeException.class); customErrorCodes.setCustomTranslations(new CustomSQLErrorCodesTranslation[] {customTranslation}); SQLErrorCodeSQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator(); sext.setSqlErrorCodes(customErrorCodes); // Should custom translate this SQLException badSqlEx = new SQLException("", "", 1); assertEquals(CustomErrorCodeException.class, sext.translate(TASK, SQL, badSqlEx).getClass()); assertEquals(badSqlEx, sext.translate(TASK, SQL, badSqlEx).getCause()); // Shouldn't custom translate this SQLException invResEx = new SQLException("", "", 3); DataIntegrityViolationException diex = (DataIntegrityViolationException) sext.translate(TASK, SQL, invResEx); assertEquals(invResEx, diex.getCause()); // Shouldn't custom translate this - invalid class exception.expect(IllegalArgumentException.class); customTranslation.setExceptionClass(String.class); }
public class DataIntegrityViolationExceptionsAdvice { public void afterThrowing(DataIntegrityViolationException ex) throws DataIntegrityViolationException { // extract the affected database constraint name: String constraintName = null; if ((ex.getCause() != null) && (ex.getCause() instanceof ConstraintViolationException)) { constraintName = ((ConstraintViolationException) ex.getCause()).getConstraintName(); } // create a detailed message from the constraint name if possible String message = ConstraintMsgKeyMappingResolver.map(constraintName); if (message != null) { throw new DetailedConstraintViolationException(message, ex); } throw ex; } }
/** * Handle DataIntegrityViolationException, inspects the cause for different DB causes. * * @param ex the DataIntegrityViolationException * @return the ApiError object */ @ExceptionHandler(DataIntegrityViolationException.class) protected ResponseEntity<Object> handleDataIntegrityViolation(DataIntegrityViolationException ex, WebRequest request) { if (ex.getCause() instanceof ConstraintViolationException) { return buildResponseEntity(new ApiError(HttpStatus.CONFLICT, "Database error", ex.getCause())); } return buildResponseEntity(new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, ex)); }
/** * Refines the data integrity violation exception to determine the translation * key from which the user message will be constructed. * * @param exception * the DataIntegrityViolationException. * @return the translation key to use. */ protected String refineIntegrityViolationTranslationKey(DataIntegrityViolationException exception) { if (exception.getCause() instanceof ConstraintViolationException) { ConstraintViolationException cve = (ConstraintViolationException) exception.getCause(); if (cve.getSQL() != null && cve.getSQL().toUpperCase().contains("DELETE")) { return "error.fk.delete"; } if (cve.getConstraintName() != null) { if (cve.getConstraintName().toUpperCase().contains("FK")) { return "error.fk.update"; } return "error.unicity"; } return "error.integrity"; } return "error.integrity"; }