• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

Translator 종류

23.03.09 21:09 작성 조회수 397

0

안녕하세요 스프링의 편한 예외 전환 강의 감사합니다.

 

궁금한 점이 있습니다.

repository에서 sql문법에러든 DuplicateKey 에러든 자동적으로 넘어온다고 했잖아요?

그런데 그럴려면 각각 대충 예상하고 Repository 에서 Translator 종류를 다르게 정의해야 하죠?

예를 들어 강의에서는

선언 
private final SQLExceptionTranslator exTranslator;

(중략)

//생성자에서
this.exTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);

(중략)
// catch 부분에서
throw exTranslator.translate("save", sql, e);

라고 했는데요

위와 같은 상황에서는 DuplicateKeyException은 터질 수 없는 것 맞죠?

SQLExceptionTranslator 인터페이스를 구현하고 있는 클래스에는 DuplicateKeyException 클래스가 없더라구요 (DuplicateKeyException는 올라가보니 NonTransientDataAccessException 클래스를 상속 받을받음)

 

그렇다면 변형된 스프링 에러가 넘어오게 하려면(translator) 각각 다른 Translator 인터페이스와 그에 맞는 구현클래스를 사용해야 하는 것 맞을까요?

답변 1

답변을 작성해보세요.

3

y2gcoder님의 프로필

y2gcoder

2023.03.09

안녕하세요, highjune 님. 공식 서포터즈 y2gcoder 입니다.

먼저 SQLErrorCodeSQLExceptionTranslator의 다이어그램을 보여드리겠습니다

image

위의 사진에서 보시면 SQLExceptionTranslator는 최상위 인터페이스, 그리고 SQLErrorCodeSQLExceptionTranslator는 그 구현체인 것을 알 수 있습니다. SQLExceptionTranslator를 다른 예외 변환기 구현체들이 상속하고 있고,

해당 인터페이스를 보시면

@FunctionalInterface
public interface SQLExceptionTranslator {

	/**
	 * Translate the given {@link SQLException} into a generic {@link DataAccessException}.
	 * <p>The returned DataAccessException is supposed to contain the original
	 * {@code SQLException} as root cause. However, client code may not generally
	 * rely on this due to DataAccessExceptions possibly being caused by other resource
	 * APIs as well. That said, a {@code getRootCause() instanceof SQLException}
	 * check (and subsequent cast) is considered reliable when expecting JDBC-based
	 * access to have happened.
	 * @param task readable text describing the task being attempted
	 * @param sql the SQL query or update that caused the problem (if known)
	 * @param ex the offending {@code SQLException}
	 * @return the DataAccessException wrapping the {@code SQLException},
	 * or {@code null} if no specific translation could be applied
	 * @see org.springframework.dao.DataAccessException#getRootCause()
	 */
	@Nullable
	DataAccessException translate(String task, @Nullable String sql, SQLException ex);

}

위에 보이시는 것처럼 DataAccessException을 리턴타입으로 하고 있는 것을 볼 수 있습니다. 그리고 강의에서 배우셨다시피 DataAccessException은 DuplicateKeyException을 포함한 스프링에서 제공하는 데이터 접근 계층 관련 예외의 최상위입니다.

밑은 DuplicateKeyException의 다이어그램입니다!

image

역시 상위에 DataAccessException이 있습니다.

그리고 위에 제시했던 구현체로 보여주셨던 SQLErrorCodeSQLExceptionTranslator 에서 doTranslate() 부분을 보시면

image실제로 DuplicateKeyException을 반환해주는 부분이 있습니다.

기본적으로 스프링은 JDBC에서 위의 데이터 접근 계층 관련 예외 추상화를 위해 SQLErrorCodeSQLExceptionTranslator을 기본으로 사용하고 있기 때문에 따로 인터페이스와 구현체를 바꾸실 필요가 없습니다. 상속과 구현하는 관계만 주의깊게 보시면 이해하실 수 있으실 것 같습니다 :)

결론만 말씀드리면 스프링은 SQLErrorCodeSQLExceptionTranslator로 sql-error-codes.xml에 있는 데이터베이스 관련 에러코드를 바탕으로 예외 추상화를 해주고 있습니다.

감사합니다.