http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#dao をテキトーに訳した。
17. DAO support
17.1 Introduction
SpringのData Access Object (DAO)サポートの目的は一貫性のある方法でJDBC, Hibernate, JPA, JDOなどのデータアクセス技術との組み合わせを容易にすることです。これにより前述の永続化技術の乗り換えを容易に行えるようになり、それぞれの技術に固有の例外キャッチなどに気を配るコードを書く必要もなくなります。
17.2 Consistent exception hierarchy
Springでは、SQLException
など個々の技術に固有の例外を、ルート例外にDataAccessException
を持つ例外クラス階層へと、使いやすい形に変換します。この例外クラスはオリジナルの例外をラップするため、何らかのエラーが発生したことを示す情報を失うリスクはありません。
JDBCの例外に加え、SpringはHibernate固有の例外をラップし、プロプライエタリなチェック例外(Hibernate 3.0より前のHibenateの場合)をランタイム例外に変換します(同様なことがJDOとJPAの例外にも当てはまります)。これにより、良くありがちで回復不能な永続化の例外を、DAO等で例外宣言とcatch-and-throwブロックという面倒なボイラープレートを書くことなしに、適切なレイヤーで処理可能になります。(何らかの処理が必要な例外については依然として対処が必要です。)上述の通り、JDBC例外(DB固有のダイアレクト含む)も同じ階層に変換されるため、一貫性のあるプログラミングモデルでJDBCに対する操作が可能です。
上記と同様なことが、Springがサポートする各種ORMフレームワークのテンプレートに対して言えます。インターセプターベースのクラスを使う場合、アプリケーションはHibernateExceptions
とJDOExceptions
の処理をする必要があり、可能であれば、それぞれSessionFactoryUtils’ `convertHibernateAccessException(..)
もしくはconvertJdoAccessException()
メソッドにデリゲートするのが望ましいです。これらのメソッドはその例外をorg.springframework.dao
の例外階層に適合するように変換します。JDOExceptions
は未チェックなので単に再スローすることも可能なため、例外の観点では汎用的なDAO抽象化を犠牲にしていると言うことも出来ます。
Springが提供する例外階層を以下に示します。(以下の図のクラス階層はDataAccessException
のサブセットのみな点に注意してください。)
17.3 Annotations used for configuring DAO or Repository classes
Data Access Objects (DAOs)やリポジトリが例外変換を行うよう保証する最良の方法は@Repository
アノテーションを使うことです。このアノテーションにより、XML設定を書くことなく、DAOとリポジトリの発見と設定のためのコンポーネントスキャンが可能となります。
@Repository public class SomeMovieFinder implements MovieFinder { // ... }
DAOやリポジトリの実装は永続化リソースにアクセスする必要があり、永続化リソースは使用する永続化技術に依存します。たとえば、JDBCベースのリポジトリはJDBCのDataSource
にアクセスする必要があり、JPAベースのリポジトリはEntityManager
にアクセスする必要があります。これを実現する最も簡単な方法は、@Autowired
, @Inject
, @Resource
, @PersistenceContext
などで、リソースの依存性をDIすることです。以下はJPAリポジトリの例です。
@Repository public class JpaMovieFinder implements MovieFinder { @PersistenceContext private EntityManager entityManager; // ... }
クラシックなHibernate APIを使用する場合はSessionFactoryをDIします。
@Repository public class HibernateMovieFinder implements MovieFinder { private SessionFactory sessionFactory; @Autowired public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } // ... }
最後のサンプルは一般的なJDBCのサポートです。DataSource
を使用するSimpleJdbcCall
などのデータアクセスサポートやJdbcTemplate
を生成する初期化メソッドにDataSource
をDIしています。
@Repository public class JdbcMovieFinder implements MovieFinder { private JdbcTemplate jdbcTemplate; @Autowired public void init(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } // ... }
上記のアノテーションを利用するためのアプリケーションコンテキストの設定方法の詳細については個々の永続化技術のドキュメントを参照してください。