SpringとHibernateを使用したDAO
1. 概要
この記事では、DAOをSpringとHibernateで実装する方法を説明します。 コアHibernate構成については、以前の Hibernate 5 withSpringの記事を確認してください。
2. これ以上の春のテンプレートはありません
Spring3.0およびHibernate3.0.1以降、Hibernateセッションを管理するためにSpringHibernateTemplateは不要になりました。 コンテキストセッション– Hibernate によって直接管理され、トランザクションのスコープ全体でアクティブなセッションを利用できるようになりました。
結果として、HibernateTemplateの代わりにHibernateAPIを直接使用することがベストプラクティスになりました。これにより、DAOレイヤーの実装がSpringから完全に切り離されます。
2.1. HibernateTemplateなしの例外変換
例外変換は、 HibernateTemplate の責任の1つであり、低レベルのHibernate例外をより高レベルの一般的なSpring例外に変換します。
テンプレートがない場合でも、このメカニズムは有効であり、@Repositoryアノテーションが付けられたすべてのDAOに対してアクティブです。 内部的には、これはすべての @RepositoryBeanにSpringコンテキストで見つかったすべてのPersistenceExceptionTranslatorを通知するSpringBeanポストプロセッサーを使用します。
覚えておくべきことの1つは、例外変換ではプロキシが使用されるということです。 SpringがDAOクラスの周りにプロキシを作成できるようにするには、これらをfinalとして宣言してはなりません。
2.2. テンプレートを使用しないHibernateセッション管理
コンテキストセッションのHibernateサポートが発表されたとき、HibernateTemplateは本質的に廃止されました。 実際、このクラスのJavadocは、この側面を強調しています(元の部分から太字になっています)。
注:Hibernate 3.0.1以降、トランザクションHibernateアクセスコードはプレーンなHibernateスタイルでコーディングすることもできます。 したがって、新しく開始されたプロジェクトでは、{@ link org.hibernate.SessionFactory#getCurrentSession()}に基づいて、代わりに標準のHibernate3スタイルのコーディングデータアクセスオブジェクトを採用することを検討してください。
3. DAO
まず、ベースDAOから始めます。これは、一般的な汎用操作をサポートし、エンティティごとに拡張できる、抽象化されたパラメーター化されたDAOです。
public abstract class AbstractHibernateDao<T extends Serializable> {
private Class<T> clazz;
@Autowired
protected SessionFactory sessionFactory;
public final void setClazz(final Class<T> clazzToSet) {
clazz = Preconditions.checkNotNull(clazzToSet);
}
// API
public T findOne(final long id) {
return (T) getCurrentSession().get(clazz, id);
}
public List<T> findAll() {
return getCurrentSession().createQuery("from " + clazz.getName()).list();
}
public T create(final T entity) {
Preconditions.checkNotNull(entity);
getCurrentSession().saveOrUpdate(entity);
return entity;
}
public T update(final T entity) {
Preconditions.checkNotNull(entity);
return (T) getCurrentSession().merge(entity);
}
public void delete(final T entity) {
Preconditions.checkNotNull(entity);
getCurrentSession().delete(entity);
}
public void deleteById(final long entityId) {
final T entity = findOne(entityId);
Preconditions.checkState(entity != null);
delete(entity);
}
protected Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
ここで興味深い点がいくつかあります。前述のように、抽象DAOはSpringテンプレート( HibernateTemplate など)を拡張しません。 代わりに、Hibernate SessionFactory はDAOに直接挿入され、公開されるコンテキスト Session を通じて、メインのHibernateAPIの役割を果たします。
this.sessionFactory.getCurrentSession();
また、コンストラクターは、エンティティの Class を、汎用操作で使用されるパラメーターとして受け取ることに注意してください。
ここで、このDAO の実装例を見てみましょう、 Fooエンティティの場合:
@Repository
public class FooDAO extends AbstractHibernateDAO< Foo > implements IFooDAO{
public FooDAO(){
setClazz(Foo.class );
}
}
4. 結論
この記事では、HibernateとSpringを使用した永続層の構成と実装について説明しました。
DAOレイヤーのテンプレートへの依存をやめる理由と、トランザクションとHibernateセッションを管理するためにSpringを構成する際の落とし穴について説明しました。 最終的な結果は、Springにコンパイル時の依存がほとんどない、軽量でクリーンなDAO実装です。
この単純なプロジェクトの実装は、githubプロジェクトにあります。