Hibernate openSession () vs getCurrentSession ()

130

Saya punya beberapa pertanyaan tentang menggunakan Hibernate di aplikasi web JSP.

  1. Untuk apa nilai itu hibernate.current_session_context_class?

  2. Lalu, manakah dari pernyataan berikut yang harus digunakan? Dan mengapa?

     Session s = HibernateUtil.getSessionFactory().openSession();
     Session s = HibernateUtil.getSessionFactory().getCurrentSession()
  3. Terakhir, mana yang lebih baik "satu sesi per aplikasi web" atau "satu sesi per permintaan"?

wannik
sumber

Jawaban:

145

Sebagaimana dijelaskan dalam posting forum ini , 1 dan 2 saling terkait. Jika Anda menetapkan hibernate.current_session_context_classuntuk utas dan kemudian menerapkan sesuatu seperti filter servlet yang membuka sesi - maka Anda dapat mengakses sesi itu di tempat lain dengan menggunakan SessionFactory.getCurrentSession().

SessionFactory.openSession()selalu membuka sesi baru yang harus Anda tutup setelah Anda selesai dengan operasi. SessionFactory.getCurrentSession()mengembalikan sesi terikat ke konteks - Anda tidak perlu menutup ini.

Jika Anda menggunakan Spring atau EJB untuk mengelola transaksi, Anda dapat mengonfigurasinya untuk membuka / menutup sesi bersama dengan transaksi.

Anda tidak boleh menggunakan one session per web app- sesi bukan objek utas aman - tidak dapat dibagikan oleh banyak utas. Anda harus selalu menggunakan "satu sesi per permintaan" atau "satu sesi per transaksi"

gkamal
sumber
Terima kasih banyak, @gkamal. Saya melihat kode di Open Session in View document. (Tautan Anda menunjuk ke dokumen-dokumen itu.) Penulis menyarankan penggunaan filter. Dalam kode filternya, dia tidak menelepon openSession()atau close(). Dia hanya menelepon getCurrentSession(). Saya kira ia menetapkan current_session_contextuntuk thread. Sekarang saya pikir saya mengerti getCurrentSession(). Namun, saya tidak tahu kapan saya harus menggunakannya openSession().
wannik
4
Anda akan menggunakan OpenSession jika Anda tidak ingin sesi terikat pada konteks apa pun. Ada beberapa situasi ketika Anda membutuhkan sesi yang berbeda - selain satu terikat ke konteks (Hibernate Interceptors memiliki batasan bahwa Anda tidak dapat menggunakan sesi asli) - dalam kasus tersebut Anda akan menggunakan OpenSession alih-alih currentSession. OpenSession membuat sesi baru yang harus Anda tutup secara eksplisit. Misalnya, dalam metode DAO Anda akan memanggil OpenSession - gunakan sesi tersebut dan tutup.
gkamal
Saya menggunakan getCurrentSession (); karena saya diinisialisasi di listener not filter apakah ini ok dari pandangan Anda; Saya menggunakan servlet mvc2 jsp
shareef
@gkamal - Saya punya pertanyaan terkait Sessions. Bisakah Anda membantu saya dengan hal ini di - stackoverflow.com/questions/23351083/… . Terima kasih dan chenqui.
Erran Morad
IMO, adalah praktik yang baik untuk membiarkan setiap utas memiliki Sesi sendiri, dan hanya satu Sesi, kan?
coderz
31

Jika kita berbicara tentang SessionFactory.openSession ()

  • Itu selalu membuat objek Sesi baru.
  • Anda perlu menyiram dan menutup objek sesi secara eksplisit.
  • Dalam lingkungan berulir tunggal, ini lebih lambat daripada getCurrentSession ().
  • Anda tidak perlu mengonfigurasi properti apa pun untuk memanggil metode ini.

Dan Jika kita berbicara tentang SessionFactory.getCurrentSession ()

  • Itu membuat Sesi baru jika tidak ada, yang lain menggunakan sesi yang sama yang ada dalam konteks hibernasi saat ini.
  • Anda tidak perlu menyiram dan menutup objek sesi, itu akan secara otomatis dijaga oleh Hibernate secara internal.
  • Dalam lingkungan berulir tunggal lebih cepat daripada openSession ().
  • Anda perlu mengonfigurasi properti tambahan. "hibernate.current_session_context_class" untuk memanggil metode getCurrentSession (), jika tidak maka akan memunculkan eksepsi.
Ramu Agrawal
sumber
Jawaban di atas memberi tahu untuk tidak menggunakan satu sesi per webapp. Jadi jika saya menggunakan getCurrentSession, itu akan menggunakan kembali sesssion yang sama, bukan?
parsecer
9

openSession: Saat Anda menelepon SessionFactory.openSession, ia selalu membuat Sessionobjek baru dan memberikannya kepada Anda.

Anda perlu menyiram dan menutup objek sesi ini secara eksplisit.

Karena objek sesi tidak aman utas, Anda perlu membuat satu objek sesi per permintaan dalam lingkungan multi-utas dan satu sesi per permintaan dalam aplikasi web juga.

getCurrentSession: Ketika Anda menelepon SessionFactory.getCurrentSession, itu akan memberi Anda objek sesi yang dalam konteks hibernasi dan dikelola oleh hibernasi secara internal. Itu terikat pada ruang lingkup transaksi.

Ketika Anda menelepon SessionFactory.getCurrentSession, itu membuat yang baru Sessionjika tidak ada, jika tidak gunakan sesi yang sama yang ada dalam konteks hibernasi saat ini. Secara otomatis flushes dan menutup sesi ketika transaksi berakhir, jadi Anda tidak perlu melakukannya secara eksternal.

Jika Anda menggunakan hibernasi dalam lingkungan berulir tunggal, Anda dapat menggunakannya getCurrentSession, karena kinerjanya lebih cepat dibandingkan dengan membuat sesi baru setiap kali.

Anda perlu menambahkan properti berikut ke hibernate.cfg.xml untuk menggunakan getCurrentSessionmetode:

<session-factory>
    <!--  Put other elements here -->
    <property name="hibernate.current_session_context_class">
          thread
    </property>
</session-factory>
Neeraj Gahlawat
sumber
Bukankah servlet membuka utas baru untuk setiap permintaan? Jadi jika itu adalah webapp Java, itu sudah bukan lingkungan single-threaded?
parsecer
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>                       |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
Joby Wilson Mathews
sumber
-6

SessionFactory: "Satu SessionFactory per aplikasi per DataBase" (mis., Jika Anda menggunakan 3 DataBase dalam aplikasi kami, Anda perlu membuat objek sessionFactory per setiap DB, benar-benar Anda perlu membuat 3 sessionFactory, atau jika Anda hanya memiliki satu DataBase One sessionfactory cukup ).

Sesi: "Satu sesi untuk satu siklus permintaan-respons". Anda dapat membuka sesi saat permintaan datang dan Anda dapat menutup sesi setelah proses permintaan selesai. Catatan: -Jangan gunakan satu sesi untuk aplikasi web.

cantik
sumber