
스프링 예외 추상화 이해
- 서비스, 컨트롤러 계층에서 예외 처리가 필요하면 특정 기술에 종속적인
SQLException 같은 예외를 직접 사용하는 것이 아니라, 스프링이 제공하는 데이터 접근 예외를 사용하면 된다.
- 향후 JDBC에서 JPA로 구현 기술을 변경하더라도, 스프링은 JPA 예외를 적절한 스프링 데이터 접근 예외로 변환해준다.
- 스프링은 데이터베이스에서 발생하는 오류 코드를 스프링이 정의한 예외로 자동으로 변환해주는 변환기를 제공한다.
org.springframework.jdbc.support.sql-error-codes.xml
예)
@Slf4j
public class SpringExceptionTranslatorTest {
DataSource dataSource;
@BeforeEach
void init() {
dataSource = new DriverManagerDataSource(ConnectionConst.URL, ConnectionConst.USERNAME, ConnectionConst.PASSWORD);
}
@Test
void sqlExceptionErrorCode() {
String sql = "select bad grammer";
try {
Connection con = dataSource.getConnection();
PreparedStatement stmt = con.prepareStatement(sql);
stmt.executeQuery();
} catch (SQLException e) {
Assertions.assertThat(e.getErrorCode()).isEqualTo(42122);
int errorCode = e.getErrorCode();
log.info("errorCode={}", errorCode);
log.info("error", e);
}
}
@Test
void exceptionTranslator() {
String sql = "select bad grammer";
try {
Connection con = dataSource.getConnection();
PreparedStatement stmt = con.prepareStatement(sql);
stmt.executeQuery();
} catch (SQLException e) {
SQLErrorCodeSQLExceptionTranslator exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
DataAccessException resultEx = exceptionTranslator.translate("select", sql, e);
log.info("resultEx", resultEx);
Assertions.assertThat(resultEx.getClass()).isEqualTo(BadSqlGrammarException.class);
}
}
}
translate() 메서드의 첫번째 파라미터는 읽을 수 있는 설명이고, 두번째는 실행한 sql, 마지막은 발생된 SQLException 을 전달하면 된다. 이렇게 하면 적절한 스프링 데이터 접근 계층의 예외로 변환해서 반환해준다.
- 예제에서는 SQL 문법이 잘못되었으므로
BadSqlGrammarException 을 반환하는 것을 확인할 수 있다.
- 눈에 보이는 반환 타입은 최상위 타입인
DataAccessException 이지만 실제로는 BadSqlGrammarException 예외가 반환된다. 마지막에 assertThat() 부분을 확인하자.
- 참고로
BadSqlGrammarException 은 최상위 타입인 DataAccessException 를 상속 받아서 만들 어진다.