2012-02-20 8 views
7

私は、ステートレスなサーブレット(1つはユーザーを登録し、残りはデータベースを照会するために使用される)から構築されたHibernateベースのプラットフォームを持っています。Java Hibernateによるセッション管理

次のように私は、Hibernateのセッションを使用しています:

Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
if ((null == session) || (session.isOpen() == false)) { 
    session = HibernateUtil.getSessionFactory().openSession(); 
} 

現在、私はopenSession()コール(可能であれば開かれたセッションを使用しようとしている)を避けるために、サーブレットの最後にセッションを閉じないでください。

ベストプラクティスは何ですか?いつ私はこれらのセッションを終了するはずですか?

例を挙げてください。

ありがとうございます!

答えて

13

ほとんどの場合、セッションごとの要求がベストプラクティスです。つまり、リクエストの処理の始めにセッションを開き、最後にセッションを閉じます。例えば、サーブレットFilterでそれを行うことができます。

アプリケーション全体に対して1つのセッションを持つことは、第1レベルのキャッシュに多くのエンティティを蓄積するため、メモリリークです。また、複数のクライアントが同時にそれを使用すると、結果が不確定になることもあります。

あなたのコードは、アプリケーション全体に対して1つのセッションを使用していません - セッションを開き、コンテキストに格納する "現在のセッション"という概念を使用しています(ThreadLocalなど)。しかし、あなたがそれを閉じなければ、それは永遠にそこにとどまるでしょう。さらに、Webアプリケーションでスレッドが再利用され、新しい要求がある時点で閉じられていない古いセッションを取得するため、上記と同じ問題が発生します。

+0

が、どのように場合は特に、あなたを、代わりにオープンクローズセッションの要求ごとに現在のセッションを得ることについて春と冬眠を一緒にしていますか? – Shilan

3

リクエストが処理されるたびに新しいセッションを開き、リクエストが処理されるとセッションを閉じる方が良いでしょう。同様

Session session = HibernateUtil.getSessionFactory().openSession(); 

代わりの

Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 

我々はgetCurrentSession()メソッドを使用している場合は、tansaction.commit()/ロールバック()は接続を閉じます。

+0

「すべてのリクエストの新しいセッション」はアンチパターンです – zond

0

休止状態のセッションを管理するのは、すべてのリクエストに対して新しいセッションを開くのが最も良い方法です。 セッションの取得方法によって異なります。

  • あなたがsessionFactory.getCurrentSession()を使用する場合は、トランザクション のライフサイクルにバインドされ、自動的にフラッシュされ、トランザクション 端が(コミットまたはときに閉じ 「現在のセッション」を取得しますロールバック)
  • sessionFactory.openSession()を使用する場合は、 を自分で管理し、「手動で」フラッシュして閉じる必要があります。
if (!session.isOpen()) { 
     session = session.getSessionFactory().openSession(); 
     session.beginTransaction(); 
} 
0

私はより良い春のフレームワークを使用することをお勧めいたします。春には@Transactionalをメソッドレベルで使用することができ、フレームワークによって内部的に処理されるAOPを使用してセッションが自動的に作成され、トランザクションマネージャによって閉じられます(ビューインターセプタでオープンセッションを使用している場合を除く)。 all.spring

@Autowired 
EntityManager em; 

@Transactinal 
void save(User user){ 
    em.persist(user); 
} 

ザッツは楽しいです:私は、アプリケーション全体に対して1つのセッションは悪い考えであることに同意D