Spring/SpringDB

스프링 예외 추상화 이해

느리지만 꾸준하게 2022. 7. 4. 16:04

아래와 같이 스프링 데이터 접근 예외 계층에 대한 그림을 보자.

 

 

스프링이 제공하는 예외 변환기는 아래와 같은 코드이다. => SQL ErrorCode를 직접 확인하는 방법

 

SpringExceptionTranslatorTest의 코드는 아래와 같다.

@Slf4j
public class SpringExceptionTranslatorTest {

    DataSource dataSource;

    @BeforeEach
    void init() {
        dataSource = new DriverManagerDataSource(URL, USERNAME, PASSWORD);
    }

    @Test
    void sqlExceptionErrorCode() {
        String sql = "select bad grammer";

        try {
            Connection con = dataSource.getConnection();
            PreparedStatement stmt = con.prepareStatement(sql);
            stmt.executeQuery();
        } catch (SQLException e) {
            // h2DB인 경우에 42122
            assertThat(e.getErrorCode()).isEqualTo(42122);
            int errorCode = e.getErrorCode();
            log.info("errorCode={}", errorCode);
            log.info("error", e);
        }
    }

 

 

 

 

스프링은 또 아래와 같이 예외 변환기를 제공한다.

BadSqlGrammarException

 

아래 코드를 실행하면 BadSqlGrammarException이 발생한다.

@Test
    void exceptionTranslator() {

        String sql = "select bad grammer";

        try {
            Connection con = dataSource.getConnection();
            PreparedStatement stmt = con.prepareStatement(sql);
            stmt.executeQuery();
        } catch (SQLException e) {
            assertThat(e.getErrorCode()).isEqualTo(42122);
            //org.springframework.jdbc.support.sql-error-codes.xml


            SQLErrorCodeSQLExceptionTranslator exTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);

            // BadSqlGrammarException
            DataAccessException resultEx = exTranslator.translate("select", sql, e);
            log.info("reslutEx", resultEx);
            assertThat(resultEx.getClass()).isEqualTo(BadSqlGrammarException.class);
        }
    }

 

스프링이 제공하는 SQL 예외 변환기는 다음과 같이 사용한다

SQLExceptionTranslator exTranslator = new
SQLErrorCodeSQLExceptionTranslator(dataSource);
DataAccessException resultEx = exTranslator.translate("select", sql, e);
state '42S22', error code '42122', message [Column "BAD" not found; SQL statement:
select bad grammer [42122-212]]; SQL was [select bad grammer] for task [select]
15:39:26.102 [main] INFO hello.jdbc.exception.translator.SpringExceptionTranslatorTest - reslutEx
org.springframework.jdbc.BadSqlGrammarException: select; bad SQL grammar [select bad grammer]; nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "BAD" not found; SQL statement:

 

각각의 DB마다 SQL ErrorCode는 다른데 스프링은 어떻게 각각의 DB가 제공하는 SQL ErrorCode까지 고려해서 예외를 변환할 수 있는지는 sql-error-codes.xml에서 답이 있다.

<bean id="MySQL" class="org.springframework.jdbc.support.SQLErrorCodes">
		<property name="databaseProductNames">
			<list>
				<value>MySQL</value>
				<value>MariaDB</value>
			</list>
		</property>
		<property name="badSqlGrammarCodes">
			<value>1054,1064,1146</value>
		</property>
		<property name="duplicateKeyCodes">
			<value>1062</value>
		</property>
		<property name="dataIntegrityViolationCodes">
			<value>630,839,840,893,1169,1215,1216,1217,1364,1451,1452,1557</value>
		</property>
		<property name="dataAccessResourceFailureCodes">
			<value>1</value>
		</property>
		<property name="cannotAcquireLockCodes">
			<value>1205,3572</value>
		</property>
		<property name="deadlockLoserCodes">
			<value>1213</value>
		</property>
	</bean>

 

 

 

 

 

 

 

 

 

 

<출처 김영한:스프링 DB 1편 - 데이터 접근 핵심 원리>

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-db-1/dashboard

 

스프링 DB 1편 - 데이터 접근 핵심 원리 - 인프런 | 강의

백엔드 개발에 필요한 DB 데이터 접근 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 DB 접근 기술의 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., - 강의

www.inflearn.com