본문 바로가기
Java

[Java] SQLException에 대해서 / 무분별한 try-catch절

by bkuk 2023. 3. 24.

무분별한 SQLException에 대한 처리

 

우선, 아래 코드를 보자.

// 1. 클라이언트가 전달한 userId로 user 객체 가져옴
try {
    user = userDao.findByUserId( req.getParameter("userId") );
} catch (SQLException e) {
    e.printStackTrace();
}

// 2. user 객체를 수정함
user.updateUser(
        req.getParameter("userId"), 
        req.getParameter("password"), 
        req.getParameter("name"), 
        req.getParameter("email"));

// 3. Db에 다시 업데이트함
try {
    userDao.update(user);
} catch (SQLException e) {
    e.printStackTrace();
}

 

SQLException은 컴파일타임 Exception이기 때문에 매번 위와 같이 반드시 try-catch절을 통해서 Exception 처리를 해야 한다. 컴파일타임 Exception은 Checked Exception과 같고, 이에 반대되는 개념으로는 UnChecked Exception이라고 불리우는 런타임 Exception이 있다. 아래 표를 보면서 확인해보자.

구분 Checked Exception UnChecked Exception
확인 시점 컴파일(Compile) 시점 런타임(Runtime) 시점
처리 여부 반드시 예외 처리해야 함 명시적으로 하지 않아도 됨
종류 IOException, ClassNotFoundException 등 NullPointerException, ClassCastException 등

 

위 코드에서, SQLException이 발생하면 catch절을 통해서

e.printStackTrace();

가 실행된다.

따라서, SQLException을 catch한다고 해서 에러 로그를 남기는 것외에 별달리 다른 작업을 할 부분이 생각나지 않는다. 컴파일타임 Exception으로 설계하지 않아도 되는 곳에서 컴파일타임 Exception을 사용함으로써 불필요하게 try-catch절로 감싸야하며, 이는 소스코드의 가독성을 떨어트리는 주범이 되고 있다.

 

 

SQLException을 런타임 Exception으로 변환해 throw하자.

 

RuntimeException을 상속하는 커스텀 Exception(DataAccessException과 같은 이름)을 추가한 후 SQLException을 새로 추가한 커스텀 Exception을 변환해 throw 하도록 구현 한다.

 

RuntimeException을 상속하는 커스텀 Exception

public class DataAccessException extends RuntimeException {
	private static final long serialVersionUID = 1L;
    
	public DataAccessException() {
		super();
	}

	public DataAccessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}

	public DataAccessException(String message, Throwable cause) {
		super(message, cause);
	}

	public DataAccessException(String message) {
		super(message);
	}

	public DataAccessException(Throwable cause) {
		super(cause);
	}
}

 

JdbcTemplate 리팩토링

  • SQLException이 발생하면 DataAccessException을 던짐.
public class JdbcTemplate{
	
    public void update(String query, PreparedStatementSetter pss) throws DataAccessException {
		[...]
        } catch (SQLException e) {
        	throw new DataAccessException();
        }
    }
    public <T> List<T> query(String query, RowMapper<T> rowMapper, 
    	PreparedStatementSetter pss) throws DataAccessException {
		[...]
    	} catch (SQLException e) {
    		throw new DataAccessException();
    	} finally {
    		try {
	    		if (rs != null) {
	    			rs.close();
	    		}
    		} catch (SQLException e) {
    			throw new DataAccessException();
    		}
    	}
    }

 

 

댓글