DAO를 굳이 따로 만들어서 사용하는 이유는 무엇일까?
가장 중요한 이유는 데이터 액세스 로직을 담은 코드를 다른 코드에서 분리해 놓기 위함이다.
이렇게 함으로써 DAO를 사용하는 쪽(주로 Service or BO)에서는 DAO가 내부에서 어떤 데이터 액세스 기술(JDBC, JDO, JPA, TopLink, Hibernate, iBatis등)을 사용하는지 신경쓰지 않아도 된다.
DAO와 사용하는 쪽은 DAO interface만 서로 공유하고 DAO는 DAO interface를 구현하고 있으면 되기 때문이다.
하지만 문제가 있다. 바로 예외(Exception)이다.
DAO가 JDBC를 사용하고 있다면 SQLException을 던질 것이고 Hibernate를 사용하고 있다면 해당 Hibernate에서 던져주는 Exception을 던질 것이다. 그러면 DAO를 사용하는 쪽은 이 예외를 받아서 처리하게 된다라고 하면 앞에서 말한 DAO가 어떤 데이터 액세스 기술을 사용하는지 신경쓰지 않아도 된다라는게 어긋나게 된다.
물론 아래와 같이 인터페이스를 각 데이터 액세스 기술에 맞게 각각 선언해 주면 되긴 된다.
public void add(User user) throws PersistentException; // JPA
public void add(User user) throws HibernateException; // Hibernate
public void add(User user) throws JdoException; // JDO
결국 인터페이스로 메소드 구현은 추상화 시켰지만 DAO에서 사용하는 구현기술마다 던지는 Exception이 다르기 때문에 메소드의 선언이 달라지는 문제가 발생한다.
결국 DAO를 사용하는 쪽에서는 DAO의 기술에 의존적이 될 수 밖에 없다.
이를 해결하기 위해 스프링은 DataAccessException에 자바의 다양한 데이터 액세스 기술을 사용할 때 발생하는 예외들을 추상화 해서 담아 놓았다.
아래는 낙관적인 락킹(Optimistic Locking)이 발생했을때 던져지는 Exception을 스프링이 추상화해 놓은 것이다. 기술에 상관없이 OptimisticLockingException만 잡아서 처리해 주면 된다.
이렇게 스프링을 활용하면 데이터 액세스 기술에 상관없이 동일한 원인에 의한 에러면 동일한 예외가 발생할 것이라고 기대할 수 있다. 하지만 이것도 완벽한 상태는 아니다.
DuplicateKeyException은 JDBC를 이용하는 경우에만 발생되며 하이버네이트나 JPA를 이용했을때는 또 다른 예외가 던져진다. 예를 들어 하이버네이트 같은 경우에는 중복키 에러가 발생하면 ConstraintViolationException을 발생시킨다.
스프링은 이를 DataIntegrityViolationException으로 변환해서 던져주게 된다.
물론 DuplicateKeyException은 DataIntegrityViolationException의 한 종류이다.
하지만 DataIntegrityViolationException은 다른 상황에서도 던져지는 예외이여서 중복키만을 처리할 때 사용하기는 애매하다.
이렇게 된 원인은 SQLException에 담긴 DB의 에러코드를 바로 해석해서 분류해주는 JDBC와는 달리 JPA나 하이버네이트, JDO같은 기술은 예외들을 세분화하고 있지 않기 때문에 스프링이 정확하게 분류하는데는 한계가 있는 것이다.
스프링의 DataAccessException이 기술에 상관없이 어느정도 추상화된 공통 예외로 변환해 주긴 하지만 근본적인 한계 때문에 완벽하다고는 할 수가 없다.
하지만 일단은 DAO를 사용하는 입장에서는 DataAccessException만 신경을 쓰면 되기 때문에 DAO에서 사용하고 있는 기술에서 던져지는 예외 때문에 메소드 정의를 여러개 할 필요는 없게 된다.
'Back-End > Spring' 카테고리의 다른 글
@ModelAttribute - 파라메터 한번에 집어넣기 (0) | 2012.09.11 |
---|---|
스프링에서 Quartz 를 사용하여 잡스케줄링 하기 [출처] [본문스크랩] 스프링에서 Quartz 를 사용하여 잡스케줄링 하기|작성자 onandme (0) | 2012.08.17 |
SpringMVC에서 간단한 ExceptionResolver 구성하기 (0) | 2012.06.26 |
스프링에서 Content Type별 View 자동 맵핑 하기 (0) | 2012.06.26 |
ibatis 태그. 자주 쓰는 것들. (0) | 2012.05.15 |