2009-03-11 31 views
11

Có thể "tự bơm" một EJB để gọi các phương thức cục bộ như các phương thức bean không? Có một số trường hợp điều này có thể thuận lợi, ví dụ như nếu các giao dịch được quản lý container được sử dụng và điều gì đó cần được thực hiện trong giao dịch mới.Có thể một hạt EJB3 "tự bơm" và gọi các phương thức riêng của nó qua EJB không?

Một ví dụ thế nào điều này có thể làm việc:

Foo.java:

@Local 
public interface FoO { 
    public void doSomething(); 
    public void processWithNewTransaction(); // this should actually be private 
} 

FooBean.java:

@Stateless 
public class FooBean implements Foo { 

    @EJB 
    private Foo foo; 

    public void doSomething() { 
     ... 
     foo.processWithNewTransaction(); 
     ... 
    } 

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    public void processWithNewTransaction() { 
     ... 
    } 
} 

Nếu tôi trích xuất processWithNewTransaction() để đậu khác, nó sẽ cần phải được được hiển thị dưới dạng phương thức công khai trong giao diện, mặc dù nó chỉ được gọi là FooBean. (Vấn đề tương tự là với mã của tôi ở trên, đó là lý do tại sao có một nhận xét trong định nghĩa giao diện.)

Một giải pháp sẽ là chuyển sang giao dịch được quản lý bean. Tuy nhiên, điều này đòi hỏi phải thay đổi toàn bộ hạt để quản lý các giao dịch của riêng mình và sẽ thêm rất nhiều đĩa nồi hơi cho tất cả các phương pháp.

+0

Ngoài các câu trả lời dưới đây: Nếu bạn không muốn có phương thức giao dịch mới trong giao diện cục bộ, bạn có thể chú thích việc thực hiện bean của bạn với cả '@Local (Foo.class)' và ' @ LocalBean' và chỉ có phương thức công khai trong lớp thực hiện. – Gandalf

+0

OP - Vui lòng cập nhật thông tin này để bỏ chọn câu trả lời đã chọn không chính xác. – NBW

Trả lời

2

Cập nhật: Như đã lưu ý bằng các câu trả lời khác, điều này thực sự là có thể về mặt kỹ thuật. Vui lòng xem câu trả lời của CsabaMichael về cách thức và lý do tại sao nó hoạt động bất chấp việc đệ quy vô tận.


Tôi không thể đưa ra câu trả lời chính xác 100% nhưng tôi khá chắc chắn rằng điều này là không thể.

Tôi nghĩ như vậy bởi vì để tiêm đậu Foo vào chính Foo bean, thùng chứa ban đầu sẽ phải tạo ra một cá thể Foo mà anh ta có thể tiêm sau đó. Nhưng để tạo ra điều này, anh ta phải tiêm một thể hiện đã có của Foo vào Foo để được tạo ra ... dẫn đến một đệ quy vô hạn.

Nếu bạn cần các giao dịch riêng biệt, tôi khuyên bạn nên giữ mọi thứ dễ dàng và tạo hai bean/giao diện độc lập.

+1

Đồng ý! Recursiv định nghĩa của đậu phiên không phải là một ý tưởng tốt. – Timo

+0

Mặc dù nó được đề nghị để giữ cho mọi thứ riêng biệt, nó thực sự là có thể (xem michael nesterenko câu trả lời) – Lutz

+0

Điều này là có thể với ejb 2.1 và 3+. Hoặc bạn có thể sử dụng '@EJB Foo self'; hoặc bạn có thể sử dụng @michael nesterenko's suggession –

1

Câu hỏi thú vị. Tôi không bao giờ tạo ra một phương thức với một thuộc tính giao tác khác nhau trong cùng một bean, đó là, điều này đòi hỏi cho việc tái cấu trúc. Điều này thường làm cho khó phát hiện lỗi trong ứng dụng khi nó phát triển.

EDIT: cố định lỗi chính tả

+0

Nó thậm chí không quan trọng hay không bạn cần phải có một thuộc tính TX khác nhau. Nếu bạn đơn giản muốn tính toán logic của bạn sao cho nó có ý nghĩa với một phương thức để gọi một phương thức khác, bạn sẽ chạy nó nếu ví dụ bạn đang truyền thực thể (cần phải ở trạng thái được quản lý) hoặc muốn tồn tại với cùng một TX người gọi hoặc bạn muốn người đánh chặn được gọi. Nếu bạn không sử dụng proxy thì không cái nào trong số đó sẽ xảy ra. – NBW

+0

@NBW: Tôi không đặt câu hỏi liệu nó có xảy ra hay không. Tôi chỉ nói nó làm cho mã của bạn khó đọc hơn và tăng cơ hội gọi phương thức không chính xác bởi vì bây giờ bạn có thể làm theo nhiều cách. Có một thành phần riêng biệt làm cho nó dễ dàng hơn để duy trì. Số dặm của bạn có thể thay đổi. – Antonio

1

tôi có xu hướng không đồng ý, thường đó là hữu ích cho việc quản lý giao dịch để gọi một phương thức đậu địa phương thông qua các thùng chứa.

Chính xác như ví dụ nếu bạn phải gọi phương thức bean cục bộ trong vòng lặp, bạn sẽ có giao dịch trên mỗi lần lặp tốt hơn so với tất cả các lần lặp lại. (logic kinh doanh được cung cấp không phải là "tất cả hoặc không có gì" như gửi hàng hoặc phát hành chứng khoán)

+0

Nó phụ thuộc vào các yêu cầu kinh doanh của bạn – deFreitas

8

Tự thực thi EJB thực sự có thể. Lý do tại sao một đệ quy vô hạn sẽ không xảy ra trong trường hợp này là khá đơn giản: container không tiêm một thực thể bean thực tế từ hồ bơi. Thay vào đó, nó sẽ tiêm một đối tượng proxy. Khi bạn gọi một phương thức trên proxy được tiêm (foo), vùng chứa sẽ nhận một cá thể bean từ nhóm của nó hoặc tạo một cá thể, nếu không có trường hợp có sẵn nào.

8

Có thể thực hiện self injection. Bạn cần sử dụng SessionContext.

SessionContext sc = ... 
sc.getBusinessObject(FooBean.class).processWithNewTransaction() 
+1

Có và một khả năng khác là thông qua một tham chiếu @EJB đến một loại đậu của riêng nó ở đây Foo. (xem [Làm thế nào để tự gọi EJB 3.x với (out) "this"] (http://www.adam-bien.com/roller/abien/entry/how_to_self_invoke_ejb)) – Lutz

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