이번글은 공식 문서에서 소개하는 DAO Suport에 대해 정리했습니다.
The Data Access Object (DAO) support in Spring is aimed at making it easy to work with data access technologies (such as JDBC, Hibernate, or JPA) in a consistent way. This lets you switch between the aforementioned persistence technologies fairly easily, and it also lets you code without worrying about catching exceptions that are specific to each technology.
Spring에서의 DAO(Data Access Object) 지원은 JDBC, Hibernate, 또는 JPA와 같은 데이터 접근 기술들을 일관된 방식으로 쉽게 사용할 수 있도록 하는 것을 목표로 합니다.
이러한 지원은 앞서 언급한 지속성 기술들 간에 비교적 쉽게 전환할 수 있게 해주며, 또한 각 기술에 특화된 예외들을 직접 처리하는 것에 대해 걱정하지 않고 코딩할 수 있도록 해줍니다.
Consistent Exception Hierarchy
Spring provides a convenient translation from technology-specific exceptions, such as SQLException to its own exception class hierarchy, which has DataAccessException as the root exception. These exceptions wrap the original exception so that there is never any risk that you might lose any information about what might have gone wrong.
Spring은 SQLException과 같은 기술에 특화된 예외들을 자신만의 예외 클래스 계층 구조로 편리하게 변환해주는 기능을 제공하며,
이 계층 구조의 최상위 예외는 DataAccessException입니다.
이러한 예외들은 원래의 예외를 감싸기 때문에, 무슨 문제가 발생했는지에 대한 정보를 잃어버릴 위험이 전혀 없습니다.
In addition to JDBC exceptions, Spring can also wrap JPA- and Hibernate-specific exceptions, converting them to a set of focused runtime exceptions. This lets you handle most non-recoverable persistence exceptions in only the appropriate layers, without having annoying boilerplate catch-and-throw blocks and exception declarations in your DAOs. (You can still trap and handle exceptions anywhere you need to though.) As mentioned above, JDBC exceptions (including database-specific dialects) are also converted to the same hierarchy, meaning that you can perform some operations with JDBC within a consistent programming model.
JDBC 예외 외에도, Spring은 JPA 및 Hibernate 특화 예외들 역시 감싸서, 집중된 런타임 예외 집합으로 변환할 수 있습니다.
이렇게 하면 대부분의 복구 불가능한(persistence) 예외들을 적절한 계층에서만 처리할 수 있으며, 귀찮은 catch-throw 블록이나 DAO에서의 예외 선언 없이도 처리 가능합니다.(물론 필요한 경우에는 어디서든 예외를 잡아 처리할 수 있습니다.)
앞서 언급한 것처럼, 데이터베이스별 방언(dialect)을 포함한 JDBC 예외들 역시 같은 계층 구조로 변환되기 때문에, JDBC로 작업하더라도 일관된 프로그래밍 모델을 사용할 수 있습니다.
The preceding discussion holds true for the various template classes in Spring’s support for various ORM frameworks. If you use the interceptor-based classes, the application must care about handling HibernateExceptions and PersistenceExceptions itself, preferably by delegating to the convertHibernateAccessException(..) or convertJpaAccessException(..) methods, respectively, of SessionFactoryUtils. These methods convert the exceptions to exceptions that are compatible with the exceptions in the org.springframework.dao exception hierarchy. As PersistenceExceptions are unchecked, they can get thrown, too (sacrificing generic DAO abstraction in terms of exceptions, though).
위에서 논의한 내용은 Spring이 여러 ORM 프레임워크를 지원할 때 사용하는 다양한 템플릿 클래스들에도 동일하게 적용됩니다.
만약 인터셉터 기반 클래스를 사용하는 경우에는, 애플리케이션이 직접 HibernateException이나 PersistenceException을 처리해야 하며, 가급적이면 SessionFactoryUtils의 convertHibernateAccessException(..) 또는 convertJpaAccessException(..) 메서드를 통해 처리하는 것이 좋습니다.
이 메서드들은 예외를 org.springframework.dao 예외 계층 구조와 호환되는 예외로 변환해줍니다.
PersistenceException은 체크되지 않은(unchecked) 예외이기 때문에 그냥 던질 수도 있지만, 이 경우에는 예외에 대한 제네릭 DAO 추상화는 포기하게 됩니다.
The following image shows the exception hierarchy that Spring provides. (Note that the class hierarchy detailed in the image shows only a subset of the entire DataAccessException hierarchy.)
다음 이미지는 Spring이 제공하는 예외 계층 구조를 보여준다.
(이미지에 나온 클래스 계층 구조는 DataAccessException 계층 전체 중 일부만 보여준다.)
쉽게 말해, Spring은 다양한 DB 예외들을 하나의 공통 예외 구조로 바꿔서,개발자가 편하고 일관되게 예외를 처리할 수 있도록 도와줍니다.
Annotations Used to Configure DAO or Repository Classes
The best way to guarantee that your Data Access Objects (DAOs) or repositories provide exception translation is to use the @Repository annotation. This annotation also lets the component scanning support find and configure your DAOs and repositories without having to provide XML configuration entries for them. The following example shows how to use the @Repository annotation:
당신의 DAO(Data Access Object)나 리포지토리들이 예외 변환(exception translation)을 제공하도록 보장하는 가장 좋은 방법은 @Repository 애너테이션을 사용하는 것입니다.
이 애너테이션은 또한 컴포넌트 스캔 기능이 XML 설정을 따로 작성하지 않고도
당신의 DAO나 리포지토리들을 찾아내고 설정할 수 있도록 해줍니다.
다음 예제는 @Repository 애너테이션을 어떻게 사용하는지를 보여줍니다.
@Repository
public class SomeMovieFinder implements MovieFinder {
// ...
}
Any DAO or repository implementation needs access to a persistence resource, depending on the persistence technology used. For example, a JDBC-based repository needs access to a JDBC DataSource, and a JPA-based repository needs access to an EntityManager. The easiest way to accomplish this is to have this resource dependency injected by using one of the @Autowired, @Inject, @Resource or @PersistenceContext annotations. The following example works for a JPA repository:
모든 DAO 또는 리포지토리 구현체는, 사용되는 영속성(persistence) 기술에 따라 영속성 리소스(persistence resource)에 접근할 수 있어야 합니다.
예를 들어, JDBC 기반의 리포지토리는 JDBC DataSource에 접근해야 하고, JPA 기반의 리포지토리는 EntityManager에 접근해야 합니다.
이 작업을 가장 쉽게 수행하는 방법은 이러한 리소스 의존성을 @Autowired, @Inject, @Resource, 또는 @PersistenceContext 애너테이션 중 하나를 사용하여 의존성 주입(injection) 하는 것입니다.
다음 예제는 JPA 리포지토리에 대해 이 방식이 어떻게 작동하는지를 보여줍니다.
@Repository
public class JpaMovieFinder implements MovieFinder {
@PersistenceContext
private EntityManager entityManager;
// ...
}
If you use the classic Hibernate APIs, you can inject SessionFactory, as the following example shows:
클래식한 Hibernate API들을 사용하는 경우, 다음 예제가 보여주는 것처럼 SessionFactory를 주입(inject) 받을 수 있습니다.
@Repository
public class HibernateMovieFinder implements MovieFinder {
private SessionFactory sessionFactory;
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
// ...
}
The last example we show here is for typical JDBC support. You could have the DataSource injected into an initialization method or a constructor, where you would create a JdbcTemplate and other data access support classes (such as SimpleJdbcCall and others) by using this DataSource. The following example autowires a DataSource
우리가 여기에서 보여주는 마지막 예제는 일반적인 JDBC 지원을 위한 것이다. 당신은 DataSource를 초기화 메서드나 생성자에 주입받을 수 있으며, 그곳에서 이 DataSource를 사용하여 JdbcTemplate이나 SimpleJdbcCall 같은 다른 데이터 접근 지원 클래스들을 생성할 수 있다. 다음 예제는 DataSource를 자동 주입(autowire) 하는 방법을 보여줍니다.
@Repository
public class JdbcMovieFinder implements MovieFinder {
private JdbcTemplate jdbcTemplate;
@Autowired
public void init(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
// ...
}
'공식문서' 카테고리의 다른 글
[Spring Docs] Package Hierarchy (0) | 2025.03.27 |
---|---|
[Spring Docs] Choosing an Approach for JDBC Database Access (0) | 2025.03.26 |
Garbage Collector #3 (0) | 2025.03.24 |
[Spring Docs] Transaction Managment #5 (0) | 2025.03.21 |
[Spring Docs] Programmatic Transaction Management #4 (0) | 2025.03.20 |