HibernateのSession管理について
久しぶりの投稿です。
Hibernate+spring frameworkと付き合って結構経ちますが、未だに混乱するので自分のための備忘録メモです。
HibernateのSessionとは
本から引用すると、「Sessionとは、永続化サービスの提供を行うもの。DBから取得したオブジェクトを保持し、状態管理を行うもの」です。
永続化サービスでは、「永続化コンテキスト*1に対する変更がDBに反映」されます。
HibernateのSession管理
セッションを取得・操作する方法はトランザクション管理方式によって異なります。
本に書いてある方法などをまとめます。
宣言的トランザクションを利用しているとき
宣言的トランザクション*2を利用しているときは、org.hibernate.SessionFactory.getCurrentSession()->セッション操作->flushのみでOKです。SessionのクローズやオープンはHibernateが行なってくれます。
session = sessionFactory.getCurrentSession();
//ここにセッション操作のコードを記述
session.flush();
プログラム内でトランザクション管理を行うとき
プログラム内でトランザクション管理を行うときには、セションのオープン、開始、操作、クローズを全てメソッド内に書かなければなりません。
session = sessionFactory.openSession();
session.beginTransaction();
//ここにセッション操作のコードを記述
session.getTransaction().commit();
session.close();
Spring frameworkを使ったHibernateのセッション管理
SpringのHibernateTemplateを使えば、Hibernateのセッション管理が楽ちんになります。
HibernateTemplateはhibernateのSession操作をラップしたメソッドを提供しており、Sessionのcloseとflushを自動でやってくれます。
ちなみに:HibernateTemplateで提供していないSession操作を行いたいとき
HibernateTemplateでhibernateが提供する全てのSession操作ができるわけではありません。できないこともあります。例えば、setMaxResults()などはHibernateTemplateでは提供していないメソッドです。こんなときは、Sessionに対して直接操作を行いたい。
このようなときは、HibernateCallbackを利用します。(参考:SpringのHibernateTemplateに定義されていない処理を実装する方法)
これを使うことで、HibernateTemplateにセッションのオープン/クローズなどの基本的操作を任せたまま、Session操作を行うことができます。
public List<Integer> Test(final param1) { HibernateCallback callback = new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { List<Integer> results = session .createQuery("SELECT ...") .setParameter("param1", param1) .setMaxResults(1) .list(); if(!results.isEmpty()) return results; return null; } }; return super.getHibernateTemplate().execute(callback); }
ちなみにHibernateCallbackではなくHibernateTemplate.getSessionFactory.getCurrentSession()で、現在のSessionが取得でき、直接セッション操作を行うことができます。
しかし、あまりお勧めできません。もしgetCurrentSessionを使うと、セッションのオープン/クローズなどは明示的に書かなくてはなくなり、コードの混乱を招きます。HibernateTemplateを使うと決めたら、Sessionの基本的操作は全てそこに任せるべきです。callbackを使う方法が正攻法だと思います。