2017-05-11 15 views
0

私は、EJBと自己呼び出しとトランザクションに関するより理論的な、ソフトウェア設計の質問を持っています。EJBの自己呼び出しと自己注入

私は、このEJBにもある別のメソッドを使ってEJB-sメソッドの1つを呼び出すEJBクラスがあるとしましょう。しかし、私はトランザクションの注釈機能を2番目の方法で順番に使用したいと考えています。より具体的には:

@Local(BorrowingService.class) 
@Stateless 
public class BorrowingServiceBean implements BorrowingService { 

    static final JcanLogger LOG = JcanLoggerFactory 
      .getLogger(BorrowingServiceBean.class); 

    @PersistenceContext(unitName = ApplicationConstants.PERSISTENCE_UNIT_NAME) 
    protected EntityManager em; 

    @Resource 
    private SessionContext sessionContext; 

    @EJB 
    private PersonService personService; 

    @EJB 
    private StatusBean statusBean; 

    @EJB 
    private BookService bookService; 

    private static final long CAUSELESS_RETURN_COST = 5;  
    private static final String CHECKED_ISBN = "0201104040"; 

    public static final long PERSON_ACCOUNT_REDUCTION = 10; 

    @Override 
    public void returnBook(Long bookId, Long userId) { 
     if (bookId == null || userId == null) { 
      throw new IllegalArgumentException("bookId and userId must not be null"); 
     } 

     List<BorrowingEntity> borrowingsByUserId = getBorrowingsByUserId(userId); 

     for (BorrowingEntity borrowingEntity : borrowingsByUserId) { 
      BookEntity tmpBook = borrowingEntity.getBook(); 

      if (tmpBook.getBookId().equals(bookId)) { 
       em.remove(borrowingEntity); 
       break; 
      } 
     } 

     //recomended self invocation could be here 
     onBookReturn(userId, bookId); 
    } 


    /** 
    * Aims to run a post-processing method in a new transaction (shouldn't be removed from here, and should remain as it is). 
    * Intention: The db change followed by the exception here represents some operations that should be rolled back for some reason. 
    */ 
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    @Override 
    public void onBookReturn(Long userId, Long bookId) {  
     BookEntity book = bookService.getBookById(bookId); 
     if (CHECKED_ISBN.equals(book.getIsbnNumber())) { 
      personService.decreasePersonAccount(userId, CAUSELESS_RETURN_COST);   
      throw new InvalidOperationException("An operation has been attempted, that shouldn't be executed. This change should be rolled back."); 
     } 
    } 

} 

私はこのような状況のためのいくつかの解決策があることを知っています。 1.私は@EJBアノテーションで自己注入を使うことができました。私は自分自身にビーンを注入し、注釈付きメソッドを呼び出します。 2.少し古いですがJNDIを使用できます。 3.現在の例のSessionContextgetBusinessObjectメソッドを使用できます。 4.別のEJBを作成し、この注釈付きメソッドをそこに配置できます。

私の質問は、ソフトウェアの設計とクリーンなコードの面で良いですか?自己注入は良い方法ではないことが分かっているので、JNDIは古いですが、SessionContextソリューションもJNDIをベースにしています。別のEJBにメソッドを分離すれば、EJBテクノロジを使用するためのOOP設計を犠牲にします。このような状況で推奨される解決策は何ですか?前もってありがとう!この質問がStackoverflowの理論的なものであり、ソフトウェアエンジニアリングスタックエクスチェンジでそれを聞くことがより望ましいでしょう。コメントをお寄せください。ここから削除します。

ありがとうございます!

答えて

1

私は常にSessionContextを使用します。 @PostConstructでは、sessionContext.getBusinessObjectを呼び出し、 'self'という名前のメンバ変数を設定します。次に、ローカルメソッドを呼び出す必要があるときは、私は 'self.someMethod()'を使います。

私は別のトランザクションが必要な場合、またはそのメソッドを非同期に呼び出す場合にのみこれを行います。

+0

あなたの答えをありがとう!私も同じことをやった。 – F3R1

関連する問題