ไฮเบอร์เนต openSession () เทียบกับ getCurrentSession ()


130

ฉันมีคำถามเกี่ยวกับการใช้ Hibernate ในเว็บแอปพลิเคชัน JSP

  1. ควรมีค่าสำหรับhibernate.current_session_context_classอะไร?

  2. แล้วควรใช้ข้อความใดต่อไปนี้? และทำไม?

     Session s = HibernateUtil.getSessionFactory().openSession();
     Session s = HibernateUtil.getSessionFactory().getCurrentSession()
    
  3. สุดท้าย "หนึ่งเซสชันต่อเว็บแอป" หรือ "หนึ่งเซสชันต่อคำขอ" อันไหนดีกว่ากัน

คำตอบ:


145

ตามที่อธิบายไว้ในโพสต์ในฟอรัมนี้1 และ 2 เกี่ยวข้องกัน หากคุณตั้งค่าhibernate.current_session_context_classเป็นเธรดจากนั้นใช้บางสิ่งเช่นตัวกรอง servlet ที่เปิดเซสชัน - คุณสามารถเข้าถึงเซสชันนั้นได้ทุกที่โดยใช้SessionFactory.getCurrentSession().

SessionFactory.openSession()เปิดเซสชันใหม่ที่คุณต้องปิดเสมอเมื่อคุณดำเนินการเสร็จสิ้น SessionFactory.getCurrentSession()ส่งคืนเซสชันที่ผูกไว้กับบริบท - คุณไม่จำเป็นต้องปิดสิ่งนี้

หากคุณใช้ Spring หรือ EJB เพื่อจัดการธุรกรรมคุณสามารถกำหนดค่าให้เปิด / ปิดเซสชันพร้อมกับธุรกรรมได้

คุณไม่ควรใช้one session per web app- เซสชันไม่ใช่อ็อบเจ็กต์ที่ปลอดภัยของเธรด - ไม่สามารถแชร์กับเธรดหลายเธรดได้ คุณควรใช้ "หนึ่งเซสชันต่อคำขอ" หรือ "หนึ่งเซสชันต่อธุรกรรม"


ขอบคุณมาก @gkamal. ฉันดูรหัสในOpen Session ในเอกสารView (ลิงก์ของคุณชี้ไปที่เอกสารนั้น) ผู้เขียนแนะนำการใช้ตัวกรอง ในรหัสตัวกรองของเขาเขาไม่เรียกหรือopenSession() close()เขาโทรgetCurrentSession(). เท่านั้น ผมคิดว่าเขากำหนดที่จะcurrent_session_context threadตอนนี้ฉันคิดว่าฉันเข้าใจgetCurrentSession()แล้ว openSession()แต่ผมไม่ทราบว่าเมื่อฉันควรใช้
wannik

4
คุณจะใช้ OpenSession หากคุณไม่ต้องการให้เซสชันถูกผูกไว้กับบริบทใด ๆ มีบางสถานการณ์ที่คุณต้องการเซสชันอื่นนอกเหนือจากหนึ่งที่ผูกไว้กับบริบท (Hibernate Interceptors มีข้อ จำกัด ที่คุณไม่สามารถใช้เซสชันดั้งเดิมได้) - ในกรณีเหล่านี้คุณจะใช้ OpenSession แทน currentSession OpenSession สร้างเซสชันใหม่ที่คุณต้องปิดอย่างชัดเจนตัวอย่างเช่นในวิธี DAO คุณจะเรียก OpenSession - ใช้เซสชันและปิด
gkamal

กำลังใช้ getCurrentSession (); เพราะฉันเริ่มต้นในฟังไม่กรองสิ่งนี้ใช้ได้จากมุมมองของคุณ กำลังใช้ mvc2 jsp servlet
shareef

@gkamal - ฉันมีคำถามเกี่ยวกับSessions. โปรดช่วยฉันด้วยที่ - stackoverflow.com/questions/23351083/… . ขอบคุณและ chenqui
Erran Morad

IMO เป็นแนวทางปฏิบัติที่ดีที่จะให้แต่ละเธรดมีเซสชันของตนเองและมีเพียงเซสชันเดียวใช่ไหม
coderz

31

ถ้าเราพูดถึง SessionFactory.openSession ()

  • มันจะสร้างวัตถุเซสชันใหม่เสมอ
  • คุณจำเป็นต้องล้างและปิดวัตถุเซสชันอย่างชัดเจน
  • ในสภาพแวดล้อมแบบเธรดเดียวจะช้ากว่า getCurrentSession ()
  • คุณไม่จำเป็นต้องกำหนดค่าคุณสมบัติใด ๆ เพื่อเรียกใช้เมธอดนี้

และถ้าเราพูดถึง SessionFactory.getCurrentSession ()

  • สร้างเซสชันใหม่หากไม่มีอยู่มิฉะนั้นจะใช้เซสชันเดียวกันซึ่งอยู่ในบริบทไฮเบอร์เนตปัจจุบัน
  • คุณไม่จำเป็นต้องล้างและปิดออบเจ็กต์เซสชั่นมันจะได้รับการดูแลโดยอัตโนมัติโดย Hibernate ภายใน
  • ในสภาพแวดล้อมเธรดเดียวจะเร็วกว่า openSession ()
  • คุณต้องกำหนดค่าคุณสมบัติเพิ่มเติม "hibernate.current_session_context_class" เพื่อเรียกเมธอด getCurrentSession () มิฉะนั้นจะทำให้เกิดข้อยกเว้น

คำตอบด้านบนบอกว่าอย่าใช้เซสชันเดียวต่อเว็บแอป ดังนั้นถ้าฉันจะใช้getCurrentSessionมันจะนำ sesssion เดิมมาใช้ใหม่ใช่ไหม
พาร์เซกเกอร์

9

openSession: เมื่อคุณโทรSessionFactory.openSessionมันจะสร้างSessionวัตถุใหม่และมอบให้คุณเสมอ

คุณจำเป็นต้องล้างและปิดวัตถุเซสชันเหล่านี้อย่างชัดเจน

เนื่องจากวัตถุเซสชันไม่ใช่เธรดที่ปลอดภัยคุณจึงต้องสร้างหนึ่งเซสชันอ็อบเจ็กต์ต่อหนึ่งคำขอในสภาพแวดล้อมแบบมัลติเธรดและหนึ่งเซสชันต่อคำขอในเว็บแอ็พพลิเคชันด้วย

getCurrentSession: เมื่อคุณโทรSessionFactory.getCurrentSessionมันจะให้วัตถุเซสชันแก่คุณซึ่งอยู่ในบริบทไฮเบอร์เนตและจัดการโดยไฮเบอร์เนตภายใน ผูกพันกับขอบเขตธุรกรรม

เมื่อคุณโทรระบบSessionFactory.getCurrentSessionจะสร้างใหม่Sessionหากไม่มีอยู่มิฉะนั้นให้ใช้เซสชันเดียวกันซึ่งอยู่ในบริบทไฮเบอร์เนตปัจจุบัน มันจะล้างและปิดเซสชันโดยอัตโนมัติเมื่อธุรกรรมสิ้นสุดลงดังนั้นคุณจึงไม่จำเป็นต้องทำภายนอก

หากคุณใช้โหมดไฮเบอร์เนตในสภาพแวดล้อมเธรดเดียวคุณสามารถใช้ได้getCurrentSessionเนื่องจากประสิทธิภาพการทำงานเร็วกว่าเมื่อเทียบกับการสร้างเซสชันใหม่ในแต่ละครั้ง

คุณต้องเพิ่มคุณสมบัติต่อไปนี้ในhibernate.cfg.xmlเพื่อใช้getCurrentSessionวิธี:

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

servlet ไม่เปิดเธรดใหม่สำหรับแต่ละคำขอใช่หรือไม่ ดังนั้นหากเป็นเว็บแอป Java ก็ไม่ใช่สภาพแวดล้อมแบบเธรดเดียวอยู่แล้ว?
พาร์เซกเกอร์

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: "One SessionFactory ต่อแอปพลิเคชันต่อ DataBase" (เช่นหากคุณใช้ DataBase 3 ตัวในแอปพลิเคชันของเราคุณต้องสร้างวัตถุ sessionFactory ต่อ DB แต่ละฐานโดยรวมแล้วคุณต้องสร้าง 3 sessionFactorys หรือมิฉะนั้นหากคุณมี DataBase One sessionfactory เพียงหนึ่งเครื่อง ก็เพียงพอแล้ว)

เซสชัน: "หนึ่งเซสชันสำหรับหนึ่งรอบคำขอตอบกลับ" คุณสามารถเปิดเซสชันเมื่อมีการร้องขอและคุณสามารถปิดเซสชันได้หลังจากเสร็จสิ้นกระบวนการขอ หมายเหตุ: - อย่าใช้หนึ่งเซสชันสำหรับเว็บแอปพลิเคชัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.