Hibernate openSession () so với getCienSession ()


130

Tôi có một số câu hỏi về việc sử dụng Hibernate trong ứng dụng web JSP.

  1. Giá trị của hibernate.current_session_context_classcái gì?

  2. Sau đó, câu nào sau đây nên được sử dụng? Và tại sao?

     Session s = HibernateUtil.getSessionFactory().openSession();
     Session s = HibernateUtil.getSessionFactory().getCurrentSession()
  3. Cuối cùng, cái nào tốt hơn "một phiên cho mỗi ứng dụng web" hay "một phiên cho mỗi yêu cầu"?

Câu trả lời:


145

Như đã giải thích trong bài đăng diễn đàn này , 1 và 2 có liên quan. Nếu bạn đặt hibernate.current_session_context_classthành luồng và sau đó triển khai một cái gì đó như bộ lọc servlet mở phiên - thì bạn có thể truy cập phiên đó ở bất kỳ nơi nào khác bằng cách sử dụngSessionFactory.getCurrentSession() .

SessionFactory.openSession()luôn mở một phiên mới mà bạn phải đóng sau khi hoàn thành các thao tác. SessionFactory.getCurrentSession()trả về một phiên bị ràng buộc vào một bối cảnh - bạn không cần phải đóng cái này.

Nếu bạn đang sử dụng Spring hoặc EJB để quản lý các giao dịch, bạn có thể định cấu hình chúng để mở / đóng phiên cùng với các giao dịch.

Bạn không bao giờ nên sử dụng one session per web app- phiên không phải là một đối tượng an toàn của luồng - không thể được chia sẻ bởi nhiều luồng. Bạn phải luôn luôn sử dụng "một phiên cho mỗi yêu cầu" hoặc "một phiên cho mỗi giao dịch"


Cảm ơn bạn rất nhiều, @gkamal. Tôi nhìn vào mã trong Phiên mở trong tài liệu Xem . (Liên kết của bạn trỏ đến tài liệu đó.) Tác giả đề xuất sử dụng bộ lọc. Trong mã bộ lọc của mình, anh ta không gọi openSession()hay close(). Anh chỉ gọi getCurrentSession(). Tôi đoán ông đặt current_session_contextcho thread. Bây giờ tôi nghĩ rằng tôi hiểu getCurrentSession(). Tuy nhiên, tôi không biết khi nào nên sử dụng openSession().
Wannik

4
Bạn sẽ sử dụng OpenSession nếu bạn không muốn phiên bị ràng buộc với bất kỳ bối cảnh nào. Có một số tình huống khi bạn cần một phiên khác - ngoại trừ một phiên bị ràng buộc với bối cảnh (Bộ chặn Hibernate có một hạn chế là bạn không thể sử dụng phiên ban đầu) - trong những trường hợp đó bạn sẽ sử dụng OpenSession thay vì currentSession. OpenSession tạo một phiên mới mà bạn phải đóng một cách rõ ràng. Ví dụ, trong phương thức DAO, bạn sẽ gọi OpenSession - sử dụng phiên và đóng nó.
gkamal

đang sử dụng getCienSession (); bởi vì tôi đã khởi tạo nó trong bộ lắng nghe không lọc nên điều này ok từ quan điểm của bạn; đang sử dụng mvc2 jsp servlet
shareef

@gkamal - Tôi có một câu hỏi liên quan đến Sessions. Bạn có thể vui lòng giúp tôi với nó tại - stackoverflow.com/questions/23351083/ . Cảm ơn bạn và chenqui.
Erran Morad

IMO, đó là một thực tiễn tốt để cho mỗi luồng giữ Phiên riêng của mình và chỉ có một Phiên, phải không?
coderz

31

Nếu chúng ta nói về SessionFactory.openSession ()

  • Nó luôn tạo một đối tượng Phiên mới.
  • Bạn cần phải rõ ràng tuôn ra và đóng các đối tượng phiên.
  • Trong môi trường luồng đơn, nó chậm hơn getCienSession ().
  • Bạn không cần phải cấu hình bất kỳ thuộc tính nào để gọi phương thức này.

Và nếu chúng ta nói về SessionFactory.getCienSession ()

  • Nó tạo ra một Phiên mới nếu không tồn tại, khác sử dụng cùng một phiên trong bối cảnh ngủ đông hiện tại.
  • Bạn không cần phải tuôn ra và đóng các đối tượng phiên, nó sẽ được Hibernate tự động chăm sóc trong nội bộ.
  • Trong môi trường luồng đơn, nó nhanh hơn openSession ().
  • Bạn cần cấu hình tài sản bổ sung. "hibernate.cien_session_context_group" để gọi phương thức getCienSession (), nếu không, nó sẽ đưa ra một ngoại lệ.

Câu trả lời ở trên cho biết không sử dụng một phiên duy nhất cho mỗi ứng dụng web. Vì vậy, nếu tôi được sử dụng getCurrentSession, nó sẽ sử dụng lại cùng một sesssion, phải không?
phân tích cú pháp

9

openSession: Khi bạn gọi SessionFactory.openSession, nó luôn tạo một Sessionđối tượng mới và đưa nó cho bạn.

Bạn cần phải rõ ràng tuôn ra và đóng các đối tượng phiên này.

Vì các đối tượng phiên không phải là luồng an toàn, bạn cần tạo một đối tượng phiên cho mỗi yêu cầu trong môi trường đa luồng và một phiên cho mỗi yêu cầu trong các ứng dụng web.

getCurrentSession: Khi bạn gọi SessionFactory.getCurrentSession, nó sẽ cung cấp cho bạn đối tượng phiên trong bối cảnh ngủ đông và được quản lý bởi chế độ ngủ đông bên trong. Nó bị ràng buộc với phạm vi giao dịch.

Khi bạn gọi SessionFactory.getCurrentSession, nó tạo ra một cái mớiSession nếu nó không tồn tại, nếu không thì sử dụng cùng một phiên trong bối cảnh ngủ đông hiện tại. Nó tự động xóa và đóng phiên khi giao dịch kết thúc, vì vậy bạn không cần phải thực hiện bên ngoài.

Nếu bạn đang sử dụng chế độ ngủ đông trong môi trường đơn luồng, bạn có thể sử dụng getCurrentSession, vì nó có hiệu suất nhanh hơn so với việc tạo một phiên mới mỗi lần.

Bạn cần thêm thuộc tính sau vào hibernate.cfg.xml để sử dụng getCurrentSessionphương thức:

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

Không phải một servlet mở một chủ đề mới cho mỗi yêu cầu? Vì vậy, nếu đó là một ứng dụng web Java, thì nó đã không phải là một môi trường đơn luồng?
phân tích cú pháp

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: "Một sessionFactory cho mỗi ứng dụng cho mỗi DataBase" (ví dụ: nếu bạn sử dụng 3 DataBase trong ứng dụng của chúng tôi, bạn cần tạo đối tượng sessionFactory cho mỗi DB, hoàn toàn bạn cần tạo 3 sessionFactory. Hoặc nếu không bạn chỉ có một phiên DataBase. Là đủ ).

Phiên: "Một phiên cho một chu kỳ đáp ứng yêu cầu". bạn có thể mở phiên khi yêu cầu đến và bạn có thể đóng phiên sau khi hoàn thành quá trình yêu cầu. Lưu ý: -Không sử dụng một phiên cho ứng dụng web.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.