Khi bạn xác định một bean làm phạm vi mẫu thử nghiệm, một cá thể mới được tạo cho mỗi vị trí cần được chèn vào. Vì vậy, mỗi DAO sẽ nhận được một phiên bản khác nhau của phiên, nhưng tất cả các invocations của các phương pháp trên DAO sẽ kết thúc bằng cách sử dụng cùng một phiên. Vì phiên không phải là chủ đề an toàn nên nó không được chia sẻ trên nhiều luồng, đây sẽ là một vấn đề.
Đối với hầu hết các trường hợp, phiên phải là phạm vi giao dịch, nghĩa là phiên mới được mở khi giao dịch bắt đầu và sau đó được đóng tự động sau khi giao dịch kết thúc. Trong một vài trường hợp, nó có thể phải được mở rộng để yêu cầu phạm vi.
Nếu bạn muốn tránh sử dụng SessionFactory.currentSession - thì bạn sẽ cần phải xác định triển khai phạm vi của riêng bạn để đạt được điều đó.
Đây là thứ đã được triển khai cho JPA sử dụng proxy. Trong trường hợp JPA EntityManager được tiêm thay vì EntityManagerFactory. Thay vì @Autowired, có một chú thích @PersistenceContext mới. Một proxy được tạo ra và được tiêm trong khi khởi tạo. Khi bất kỳ phương thức nào được gọi, proxy sẽ nhận được thực thi EntityManager thực tế (sử dụng một cái gì đó tương tự như SessionFactory.getCurrentSession) và ủy quyền cho nó.
Điều tương tự cũng có thể được triển khai cho Hibernate, nhưng độ phức tạp bổ sung không đáng giá. Nó đơn giản hơn nhiều để định nghĩa một phương thức getSession trong một BaseDAO gọi nội bộ SessionFactory.getCurrentSession(). Với mã này sử dụng phiên là giống hệt với phiên tiêm.
Một trường hợp đã đọc [doc] (http://docs.jboss.org/hibernate/orm/3.5/javadoc/org/hibernate/Session.html) có nội dung 'Nếu Session có ngoại lệ, giao dịch phải được khôi phục và phiên bị hủy. Trạng thái bên trong của phiên có thể không nhất quán với cơ sở dữ liệu sau khi ngoại lệ xảy ra.' –
Bạn nên tiêm 'javax.persistence.EntityManager' nhưng vì điều đó, bạn phải nhấn mạnh khi sử dụng JPA thay thế. – Lion