2009-08-21 22 views
64

Một câu hỏi dài, xin vui lòng chịu với tôi.Tiêm EntityManager Vs. EntityManagerFactory

Chúng tôi đang sử dụng Spring + JPA cho một ứng dụng web. Nhóm của tôi đang tranh luận về việc tiêm EntityManagerFactory vào số GenericDAO (một DAO dựa trên Generics trên các dòng do APPFUSE cung cấp, chúng tôi không sử dụng JpaDaosupport vì một lý do nào đó) khi tiêm EntityManager. Chúng tôi đang sử dụng "ứng dụng được quản lý kiên trì".

Các đối số chống tiêm EntityManagerFactory là quá lớn và không cần thiết, EntityManager thực hiện những gì chúng tôi cần. Ngoài ra, như mùa xuân sẽ tạo ra một trường hợp mới của một DAO cho mỗi yêu cầu web (tôi nghi ngờ điều này) sẽ không có bất kỳ vấn đề tương tranh như trong cùng một ví dụ EntityManager được chia sẻ bởi hai chủ đề.

Lý lẽ cho tiêm EFM là thực hành tốt trên tất cả các phương pháp luôn tốt để có thể xử lý nhà máy.

Tôi không chắc đó là cách tiếp cận tốt nhất, ai đó có thể vui lòng khai sáng cho tôi?

+2

Tôi cũng hiểu rằng khi Spring tiêm EntityManager, nó là "persistence managed persistence" và Spring cũng "làm cho" chuỗi Entitymanagers an toàn. SB –

Trả lời

49

Ưu điểm và nhược điểm của việc tiêm EntityManagerFactory vs EntityManager đều được viết ra trong tài liệu Spring here, tôi không chắc liệu tôi có thể cải thiện điều đó hay không.

Nói rằng, có một số điểm trong câu hỏi của bạn cần được xóa.

... mùa xuân sẽ tạo ra một thể hiện mới của một DAO cho mọi yêu cầu web ...

Đây không phải là chính xác. Nếu DAO của bạn là một bean Spring, thì đó là một singleton, trừ khi bạn cấu hình nó theo cách khác thông qua thuộc tính scope trong định nghĩa bean. Instantiating một DAO cho mỗi yêu cầu sẽ được điên.

Đối số cho tiêm EMF là nó một thực hành tốt trên tất cả nó luôn tốt để có một xử lý cho một nhà máy .

Đối số này không thực sự chứa nước. Thực hành tốt nói chung rằng một đối tượng nên được tiêm với các cộng tác viên tối thiểu cần thực hiện công việc của mình.

6

Tôi thấy rằng việc đặt chú thích Spring @Repository trên DAO của chúng tôi và có EntityManager do Spring quản lý và được chèn bởi chú thích @PersistenceContext là cách thuận tiện nhất để mọi thứ hoạt động trôi chảy. Bạn được hưởng lợi từ sự an toàn luồng của EntityManager được chia sẻ và bản dịch ngoại lệ. Theo mặc định, EntityManager được chia sẻ sẽ quản lý các giao dịch nếu bạn kết hợp một số DAO từ một trình quản lý chẳng hạn. Cuối cùng bạn sẽ thấy rằng DAO của bạn sẽ trở thành thiếu máu.

23

Tôi đang đặt ra những gì cuối cùng tôi đã thu thập được. Từ phần "Implementing DAOs based on plain JPA" trong tham khảo Xuân:

Mặc dù trường hợp EntityManagerFactory là thread-safe, EntityManager trường hợp thì không. Trình đối tượng JPA EntityManager được tiêm giống như một EntityManager được lấy từ môi trường JNDI của máy chủ ứng dụng, như được xác định bởi đặc tả JPA.Nó ủy quyền tất cả các cuộc gọi đến EntityManager giao dịch hiện tại, nếu có; nếu không, nó rơi trở lại đối với một EntityManager mới được tạo cho mỗi hoạt động, có hiệu lực làm cho an toàn chủ đề sử dụng .

Điều này có nghĩa là theo thông số kỹ thuật JPA Các thể hiện của EntityManager không an toàn, nhưng nếu Spring xử lý chúng, chúng sẽ được tạo thành an toàn.

Nếu bạn đang sử dụng Spring, tốt hơn bạn nên tiêm EntityManagers thay vì EntityManagerFactory.

9

Tôi nghĩ rằng điều này đã được bảo hiểm tốt, nhưng chỉ để củng cố một vài điểm.

  • Các DAO, nếu tiêm bởi Spring, là một singleton theo mặc định. Bạn phải đặt rõ ràng phạm vi mẫu thử để tạo một phiên bản mới mỗi lần.

  • Máy quản lý đối tượng được tiêm bởi @PersistenceContext là chủ đề an toàn.

Điều đó đang được nói, tôi đã gặp một số vấn đề với DAO đơn trong ứng dụng đa luồng của mình. Tôi đã kết thúc việc tạo DAO một chiếc hạt nhân bản và giải quyết được vấn đề. Vì vậy, trong khi tài liệu có thể nói một điều, bạn có thể muốn kiểm tra kỹ ứng dụng của mình.

Follow-up:

Tôi nghĩ rằng một phần của vấn đề của tôi là tôi đang sử dụng

@PersistenceContext(unitName = "unit", 
    type = PersistenceContextType.EXTENDED) 

Nếu bạn sử dụng PersistenceContextType.EXTENDED, hãy nhớ bạn phải, nếu tôi hiểu đúng, đóng giao dịch theo cách thủ công. Xem chuỗi this để biết thêm thông tin.

Một Follow-up:

Sử dụng một DAO instanced là một ý tưởng vô cùng xấu. Mỗi trường hợp của DAO sẽ có bộ nhớ cache ổn định của riêng nó và các thay đổi đối với một bộ nhớ cache sẽ không được nhận dạng bởi các hạt DAO khác. Xin lỗi vì lời khuyên xấu.

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