2011-11-08 19 views
110

Tôi có một số câu hỏi về cách sử dụng Hibernate trong ứng dụng web JSP.Hibernate openSession() vs getCurrentSession()

  1. Giá trị nào là hibernate.current_session_context_class?

  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, phiên nào là "một phiên cho mỗi ứng dụng web" hay "một phiên cho mỗi yêu cầu"?

Trả lời

122

Như đã giải thích trong diễn đàn này post, 1 và 2 có liên quan. Nếu bạn đặt hibernate.current_session_context_class thành chuỗi và sau đó triển khai một cái gì đó giống 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ụng SessionFactory.getCurrentSession().

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

Nếu bạn đang sử dụng Spring hoặc EJB để quản lý giao dịch, bạn có thể định cấu hình chúng để mở/đóng phiên cùng với 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à chủ đề an toàn chủ đề - không thể chia sẻ bởi nhiều chuỗi. Bạn nên thường xuyên sử dụng "một phiên theo yêu cầu" hoặc "một phiên mỗi giao dịch"

+0

Cảm ơn bạn rất nhiều, @gkamal. Tôi nhìn vào mã trong tài liệu [Open Session in View] (http://community.jboss.org/wiki/OpenSessionInView). (Liên kết của bạn trỏ đến các 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()' hoặc 'close()'. Anh ta chỉ gọi 'getCurrentSession()'. Tôi đoán anh ta đặt 'current_session_context' thành' thread'. Bây giờ tôi nghĩ tôi hiểu 'getCurrentSession()'. Tuy nhiên, tôi không biết khi nào tôi 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ỳ ngữ cảnh nào. Có một số tình huống khi bạn sẽ cần một phiên khác - trừ một ràng buộc với ngữ cảnh (các trình chặn Hibernate có một giới hạn mà bạn không thể sử dụng phiên ban đầu) - trong những trường hợp này 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.Đối với ví dụ, trong một phương pháp DAO, bạn sẽ gọi OpenSession - sử dụng phiên làm việc và đóng nó lại. – gkamal

+0

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

-4

SessionFactory: "Một SessionFactory cho mỗi ứng dụng 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 phải tạo sessionFactory đối tượng cho mỗi DB, hoàn toàn bạn cần phải tạo 3 sessionFactorys. Nếu không bạn chỉ có một DataBase Một sessionfactory là đủ ).

Phiên: "Một phiên cho một chu kỳ phản hồi 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 tất quy trình yêu cầu. Lưu ý: -Không sử dụng một phiên cho ứng dụng web.

13

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

  • Nó luôn luôn tạo ra đối tượng Session mới.
  • Bạn cần xóa rõ ràng và đóng đối tượng phiên.
  • Trong môi trường luồng đơn, nó chậm hơn getCurrentSession.
  • Bạn không cần định 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.getCurrentSession()

  • Nó tạo ra một phiên mới nếu không tồn tại, nếu không sử dụng cùng một phiên mà là trong bối cảnh chế độ ngủ đông hiện hành.
  • Bạn không cần phải tuôn ra và đóng đối tượng phiên, nó sẽ tự động được chăm sóc bởi Hibernate nội bộ.
  • Trong môi trường luồng đơn, nó nhanh hơn openSession.
  • Bạn cần định cấu hình thuộc tính bổ sung. "hibernate.current_session_context_class" để gọi phương thức getCurrentSession, nếu không nó sẽ ném một ngoại lệ.
0
openSession :- When you call SessionFactory.openSession, it always create new Session object afresh and give it to you. 

Bạn cần xóa và đóng các đối tượng phiên một cách rõ ràng. Vì các đối tượng phiên không phải là chủ đề 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 :- When you call SessionFactory. getCurrentSession, it will provide you session object which is in hibernate context and managed by hibernate internally. It is bound to transaction scope. 
When you call SessionFactory. getCurrentSession , it creates a new Session if not exists , else use same session which is in current hibernate context. It automatically flush and close session when transaction ends, so you do not need to do externally. 
If you are using hibernate in single threaded environment , you can use getCurrentSession, as it is faster in performance as compare to creating new session each time. 
You need to add following property to hibernate.cfg.xml to use getCurrentSession method. 



<session-factory> 
<!-- Put other elements here --> 
<property name="hibernate.current_session_context_class"> 
      thread 
</property> 
</session-factory> 
Các vấn đề liên quan