2010-07-11 19 views
16

Tôi hiện đang tạo Lớp Truy cập Dữ liệu EJB3 để xử lý tất cả các hoạt động cơ sở dữ liệu trong ứng dụng Java EE 6 của tôi. Bây giờ, kể từ khi Java EE 6 cung cấp ApplicationScoped-Annotation mới, tôi tự hỏi EJB của tiểu bang nào nên có, hoặc nếu nó phải là không trạng thái.JavaEE6 DAO: Có nên là @Stateless hoặc @ApplicationScoped không?

Có thể nào tốt hơn để cho DAO là một phiên phiên @Stateless Bean hoặc một @ApplicationScoped Bean? Còn về @Singleton? Sự khác nhau giữa các tùy chọn này liên quan đến DAO là gì?

EDIT: Tôi đang sử dụng Glassfish 3.0.1 với đầy đủ Java EE 6 nền tảng

Trả lời

12

nó Whould được tốt hơn để cho các DAO là một @Stateless Session Bean, hoặc một @ApplicationScoped Bean ? Còn về @Singleton? Sự khác nhau giữa các tùy chọn này liên quan đến DAO là gì?

tôi sẽ KHÔNG sử dụng Stateless Session Beans cho DAO:

  1. EJB được gộp lại bằng container vì vậy nếu bạn có N trường hợp mỗi hồ bơi và hàng ngàn bảng, bạn chỉ cần đi để lãng phí nguồn lực (thậm chí không đề cập đến chi phí tại thời điểm triển khai).

  2. Thực hiện DAO vì SLSB sẽ khuyến khích chuỗi EJB không phải là một thực tiễn tốt từ quan điểm khả năng mở rộng.

  3. Tôi sẽ không liên kết lớp DAO với API EJB.

@Singleton được giới thiệu trong EJB 3.1 có thể làm mọi việc tốt hơn một chút nhưng tôi vẫn không triển khai DAO làm EJB. Tôi thà sử dụng CDI (và có thể là một bản mẫu tùy chỉnh, xem ví dụ this article).

Hoặc tôi sẽ không sử dụng DAO. Người quản lý thực thể của JPA là việc triển khai mẫu Domain Store và quyền truy cập gói vào một Cửa hàng miền trong DAO không thêm nhiều giá trị.

+0

Cảm ơn bạn đã trả lời! Tôi không muốn thảo luận ở đây nếu một DAO có ý nghĩa. Đối với tôi, nó có ý nghĩa để sử dụng một. Ít nhất cho đến khi Module Seam 3 Persistence sẵn sàng để sản xuất;) Vì vậy, bạn nói rằng tôi không nên buộc lớp DAO vào API EJB. Nhưng còn về giao dịch và bảo mật thì sao? Tôi sẽ sử dụng các dịch vụ đó ở đâu, nếu không phải cho các hoạt động cơ sở dữ liệu -> DAO? Các dịch vụ này không được cung cấp bởi CDI, ít nhất là không giống như cách quản lý container JavaEE6 thông thường. Hoặc có lẽ tôi nên trộn CDI và EJB? – ifischer

+0

@ifischer: DAO chắc chắn KHÔNG chịu trách nhiệm về kiểm soát giao dịch và phân giới (hoặc bảo mật), sử dụng SLSB (một Mặt tiền Phiên) cho điều đó. Vì vậy, có, sử dụng EJB và CDI. –

+5

> 'EJB được gộp bởi vùng chứa vì vậy nếu bạn có N trường hợp trên mỗi nhóm và hàng nghìn bảng' - 1. Nếu bạn có hàng ngàn bảng và hàng nghìn thực thể bạn có thể cần phải sửa đổi thiết kế của mình. Bên cạnh đó, các trường hợp EJB thường được tạo theo yêu cầu và không phải trước và chắc chắn không phải cho toàn bộ dung lượng hồ bơi cùng một lúc. Sau đó, ngay cả khi hàng ngàn người trong số họ sẽ được tạo ra, yêu cầu bộ nhớ của hàng ngàn trường hợp là chỉ một megabyte, đó là hoàn toàn không đáng kể. Có một khoản chi phí nhỏ khi khởi động máy chủ ứng dụng (mà tôi thực hiện là ý của bạn với thời gian triển khai) –

0

@Pascal: Theo ý kiến ​​của tôi, DAO của tôi không phải là "chịu trách nhiệm" về giao dịch hoặc bảo mật, vì vùng chứa quản lý các dịch vụ này. Tôi chỉ chú thích các phương thức trong DAO của tôi (chỉ để bảo mật, vì các giao dịch được xử lý tự động). Các chú thích đã "chịu trách nhiệm" chưa?

Được rồi, do đó bạn làm cho tôi suy nghĩ lại về thiết kế của mình. Hy vọng ổn của nó và không quá lạc đề, nhưng có lẽ nó giúp - đây là làm thế nào tôi đang sử dụng JEE6 hôm nay:

  • JSF truy cập một CDI Bean,
  • CDI Bean truy cập vào DAO-EJB mà "logic kinh doanh"
  • vì vậy hiện tại "logic nghiệp vụ" duy nhất của tôi đang thực hiện CRUD, sau này tôi sẽ thêm một số EJB khác cho các tác vụ quan trọng như phương pháp không đồng bộ hoặc Dịch vụ hẹn giờ.
  • DAO của tôi là chung và sử dụng Truy vấn Tiêu chí JPA2 để thực hiện các truy vấn typesafe (không có chuỗi)
  • Tôi biết rằng tôi không cần DAO để lưu giữ/cập nhật/xóa (quá đơn giản), nhưng tôi cần nó cho các truy vấn của tôi; vì vậy tôi chỉ cần đặt chúng lại với nhau

Có vấn đề gì với cách tiếp cận đó?

1

Sau khi xem xét lại, có vẻ như DAO thực sự không phải là tên phù hợp với những gì tôi muốn làm. Có lẽ nó thực sự là một mặt tiền, như Pascal nói. Tôi vừa tìm thấy Ví dụ về Kho lưu trữ Netbeans - một ứng dụng mẫu JavaEE6, xem here - nơi chúng có ItemFacade chịu trách nhiệm tìm/tạo/xóa các thực thể khỏi cơ sở dữ liệu. Đó là Bean Session không có trạng thái. Trông như thế này:

@Stateless 
public class ItemFacade implements Serializable { 
    @PersistenceContext(unitName = "catalogPU") 
    private EntityManager em; 

    public void create(Item item) { ... } 
    public void edit(Item item) { ... } 
    public void remove(Item item) { ... } 
    public Item find(Object id) { ... } 
    public List<Item> findAll() { ... } 
    public List<Item> findRange(int maxResults, int firstResult) { ... } 
    public int getItemCount() { ... } 
} 

Vì vậy, như một kết luận tôi không gọi DAO DAO của tôi nữa mà thay vào đó chỉ là ví dụ PersonEJB (tôi nghĩ rằng "PersonFacade" có thể được hiểu lầm) và làm cho nó cũng @Stateless, như tôi nghĩ ví dụ Netbeans có thể được xem là thiết kế tốt.

+0

Đó là phần cuối cùng của câu trả lời của tôi: không có DAO ở tất cả và một [mặt tiền phiên] (http: //java.sun. com/blueprints/corej2eepatterns/Patterns/SessionFacade.html) để kiểm soát giao dịch và bảo mật, SLSB là ứng cử viên tự nhiên trong Java EE. Bây giờ, tôi phải nói rằng câu trả lời trên thực sự không trả lời câu hỏi * ban đầu * của bạn và thứ hai, (hầu như) viết lại câu hỏi của bạn để phù hợp với câu trả lời của bạn không khuyến khích tôi dành nhiều thời gian hơn cho việc này. Chúc may mắn. –

+1

Đã thay đổi câu trả lời được chấp nhận. Bạn đang hạnh phúc bây giờ? ;) Bạn nói đúng, câu trả lời này không liên quan gì đến câu trả lời ban đầu của tôi. Cảm ơn bạn đã giúp đỡ. – ifischer

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