2014-09-07 19 views
13

Tôi hiện đang làm việc trên một ứng dụng sử dụng Spring Boot và Spring Data (giao diện JpaRepository chính xác) cùng với Hibernate. Một điều tôi thích về Hiberante là tính năng lưu trữ của nó - khi bạn gửi nhiều truy vấn phù hợp với một đối tượng cụ thể, bạn sẽ lấy lại cùng một cá thể của đối tượng đó trên mọi truy vấn thực thi (đối với toán tử == của Java). Tuy nhiên, khi sử dụng dữ liệu Spring và các lớp JpaRepository, điều này không phải lúc nào cũng đúng. Vì lý do đó, tôi giả định rằng có nhiều trường hợp HibernateSession tại nơi làm việc tại đây.Spring Boot & Spring Dữ liệu: phiên Hibernate được quản lý như thế nào?

Do đó, câu hỏi của tôi là: Dữ liệu mùa xuân xử lý phiên Hibernate như thế nào? Khi nào nó mở hoặc đóng chúng? Có cách nào để cấu hình nó để sử dụng cùng một phiên cho toàn bộ thời gian chạy của ứng dụng của tôi để sử dụng đầy đủ bộ nhớ cache đối tượng của Hibernate? Có lý do nào không không để thực hiện theo cách đó?

Cảm ơn,

Alan

Trả lời

19

Tôi nghĩ rằng tôi đã tìm thấy câu trả lời bản thân mình. Nếu ai đó tìm thấy câu hỏi này, đây là câu trả lời của tôi.

Spring quản lý phiên Hibernate như thế nào?

Khi gọi một phương pháp JpaRepository (hay nói chung bất kỳ phương pháp Repository), mùa xuân sẽ:

  • Hỏi SessionFactory để tạo ra một phiên mới
  • mở phiên này
  • Thực hiện gọi Repository phương pháp
  • Đóng phiên

Điều tương tự dường như giữ cho bất kỳ phương pháp nào được chú thích bằng chú thích mùa xuân @Transactional.

Hậu quả là gì?

Là một lập trình viên ...

  • bạn không cần phải quan tâm mình với các giao dịch hoặc phiên ở tất cả.
  • bạn không thể dựa vào chức năng bộ nhớ đệm của Hibernate. Điều này chỉ hoạt động trong cùng một số HibernateSession.
  • bạn phải quyết định mức tương đương của các đối tượng @Entity bằng giá trị ID Hibernate của họ, thay vì bằng cách sử dụng toán tử == của Java.
  • bạn cần phải chăm sóc mà bộ sưu tập lười biếng (ví dụ như trong một tài liệu tham khảo @OneToMany) trong @Entity lớp học của bạn (xem FetchMode.LAZY như trái ngược với FetchMode.EAGER) được sử dụng độc quyền trong một phương pháp @Transactional -annotated

Ngoài ra để tham khảo, liên kết sau đây khá hữu ích: Multiple Transactions in single session

Như với nhiều khía cạnh khác của Mùa xuân, có rất nhiều thứ để đạt được ở đây, nếu bạn sẵn sàng hy sinh kiểm soát trực tiếp ứng dụng của mình.

+4

Thực ra điều đó không đúng ... Tùy thuộc vào việc phân định giao dịch của bạn, bạn sẽ sử dụng lại phiên đã được mở. Nếu bạn có một phương thức dịch vụ được chú thích bằng '@ Transactional' (và đã thiết lập đúng hỗ trợ tx) thì Spring sẽ mở một' Session'/'EntityManager' và sử dụng lại nó cho tất cả các cuộc gọi db bạn thực hiện bên trong giao dịch đó. Ngoài ra, cần lưu ý rằng lớp dịch vụ của bạn phải là lớp giao tác KHÔNG phải lớp truy cập dữ liệu của bạn. –

+0

Cảm ơn bạn đã làm rõ. Điều này là tốt để biết. – Alan47

Các vấn đề liên quan