Hibernate openSession()とgetCurrentSession()


130

JSP WebアプリケーションでのHibernateの使用についていくつか質問があります。

  1. の値はhibernate.current_session_context_class何ですか?

  2. 次に、次のステートメントのどれを使用する必要がありますか?なぜ?

     Session s = HibernateUtil.getSessionFactory().openSession();
     Session s = HibernateUtil.getSessionFactory().getCurrentSession()
  3. 最後に、「Webアプリごとに1つのセッション」と「リクエストごとに1つのセッション」のどちらが適していますか?

回答:


145

このフォーラム投稿で説明されているように、1と2は関連しています。hibernate.current_session_context_classスレッドに設定してから、セッションを開くサーブレットフィルターのようなものを実装する場合は、を使用して他の場所にそのセッションにアクセスできますSessionFactory.getCurrentSession()

SessionFactory.openSession()操作が完了したら閉じる必要がある新しいセッションを常に開きます。SessionFactory.getCurrentSession()コンテキストにバインドされたセッションを返します-これを閉じる必要はありません。

SpringまたはEJBを使用してトランザクションを管理している場合は、トランザクションとともにセッションを開いたり閉じたりするように構成できます。

使用しないでくださいone session per web app-セッションはスレッドセーフオブジェクトではありません-複数のスレッドで共有できません。常に「リクエストごとに1セッション」または「トランザクションごとに1セッション」を使用する必要があります


@gkamalさん、ありがとうございました。Open Session in Viewドキュメントコードを確認します。(あなたのリンクはそのドキュメントを指しています。)著者はフィルターの使用を提案しています。彼のフィルターコードでは、彼はopenSession()やを呼び出していませんclose()。彼は電話するだけgetCurrentSession()です。私は彼がに設定current_session_contextすると思いますthread。今、私は理解してgetCurrentSession()いると思います。ただし、をいつ使用すればよいかわかりませんopenSession()
wannik

4
セッションをコンテキストにバインドしたくない場合は、OpenSessionを使用します。コンテキストにバインドされたセッション以外の別のセッションが必要になる場合があります(Hibernateインターセプターには、元のセッションを使用できないという制限があります)。これらの場合、currentSessionの代わりにOpenSessionを使用します。OpenSessionは、明示的に閉じる必要がある新しいセッションを作成します。たとえば、DAOメソッドでOpenSessionを呼び出します-セッションを使用して閉じます。
gkamal

getCurrentSession();を使用しています。フィルターではなくリスナーで初期化したので、これはあなたの見解では問題ありません。mvc2 jspサーブレットを使用しています
2013年

@gkamal-に関する質問がありSessionsます。-stackoverflow.com/questions/23351083/…で私を助けてくれませんか。ありがとう、chenqui。
Erran Morad 14

IMO、各スレッドに独自のセッションを保持させ、セッションを1つだけ保持させることは良い習慣です。
coderz

31

SessionFactory.openSession()について話す場合

  • 常に新しいSessionオブジェクトを作成します。
  • セッションオブジェクトを明示的にフラッシュして閉じる必要があります。
  • シングルスレッド環境では、getCurrentSession()よりも低速です。
  • このメソッドを呼び出すためにプロパティを構成する必要はありません。

そして、SessionFactory.getCurrentSession()について話す場合

  • 存在しない場合は新しいセッションを作成し、そうでない場合は現在の休止状態のコンテキストにある同じセッションを使用します。
  • セッションオブジェクトをフラッシュして閉じる必要はありません。内部的にHibernateによって自動的に処理されます。
  • シングルスレッド環境では、openSession()よりも高速です。
  • 追加のプロパティを設定する必要があります。「hibernate.current_session_context_class」を呼び出してgetCurrentSession()メソッドを呼び出します。それ以外の場合は、例外がスローされます。

上記の答えは、Webアプリケーションごとに1つのセッションを使用しないことを示しています。したがって、をgetCurrentSession使用すると、同じセッションが再利用されますね。
パーサー

9

openSession:を呼び出すとSessionFactory.openSession、常に新しいSessionオブジェクトが作成され、渡されます。

これらのセッションオブジェクトを明示的にフラッシュして閉じる必要があります。

セッションオブジェクトはスレッドセーフではないため、マルチスレッド環境ではリクエストごとに1つのセッションオブジェクトを作成し、Webアプリケーションでもリクエストごとに1つのセッションを作成する必要があります。

getCurrentSession:を呼び出すとSessionFactory.getCurrentSession、Hibernateコンテキストにあり、Hibernateによって内部的に管理されるセッションオブジェクトが提供されます。トランザクションスコープにバインドされています。

を呼び出すとSessionFactory.getCurrentSessionSession存在しない場合は新しいセッションが作成されます。それ以外の場合は、現在の休止状態のコンテキストにある同じセッションが使用されます。トランザクションが終了すると、自動的にセッションをフラッシュして閉じます。そのため、外部で行う必要はありません。

シングルスレッド環境でhibernateを使用getCurrentSessionしている場合は、毎回新しいセッションを作成するよりもパフォーマンスが速いため、を使用できます。

メソッドを使用するには、以下のプロパティをhibernate.cfg.xmlに追加する必要がありますgetCurrentSession

<session-factory>
    <!--  Put other elements here -->
    <property name="hibernate.current_session_context_class">
          thread
    </property>
</session-factory>

サーブレットはリクエストごとに新しいスレッドを開きませんか?したがって、それがJava Webアプリケーションである場合、それはすでにシングルスレッド環境ではありませんか?
パーサー

0
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Parameter            |                                openSession                                 |                                          getCurrentSession                                          |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Session  creation    | Always open new session                                                    | It opens a new Session if not exists , else use same session which is in current hibernate context. |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Session close        | Need to close the session object once all the database operations are done | No need to close the session. Once the session factory is closed, this session object is closed.    |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Flush and close      | Need to explicity flush and close session objects                          | No need to flush and close sessions , since it is automatically taken by hibernate internally.      |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Performance          | In single threaded environment , it is slower than getCurrentSession       | In single threaded environment , it is faster than openSession                                      |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Configuration        | No need to configure any property to call this method                      | Need to configure additional property:                                                              |
|                      |                                                                            |  <property name=""hibernate.current_session_context_class"">thread</property>                       |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+

-6

SessionFactory: "データベースごとにアプリケーションごとに1つのセッションファクトリ"(たとえば、アプリケーションで3つのデータベースを使用する場合、各DBごとにセッションファクトリオブジェクトを作成する必要があります。完全に3つのセッションファクトリを作成する必要があります。それ以外の場合は、データベースが1つだけの場合は1つのセッションファクトリ十分です)。

セッション:「1つの要求/応答サイクルに対して1つのセッション」。リクエストが来たときにセッションを開き、リクエストプロセスの完了後にセッションを閉じることができます。注:-Webアプリケーションに1つのセッションを使用しないでください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.