私は、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.現在の例のSessionContext
のgetBusinessObject
メソッドを使用できます。 4.別のEJBを作成し、この注釈付きメソッドをそこに配置できます。
私の質問は、ソフトウェアの設計とクリーンなコードの面で良いですか?自己注入は良い方法ではないことが分かっているので、JNDIは古いですが、SessionContextソリューションもJNDIをベースにしています。別のEJBにメソッドを分離すれば、EJBテクノロジを使用するためのOOP設計を犠牲にします。このような状況で推奨される解決策は何ですか?前もってありがとう!この質問がStackoverflowの理論的なものであり、ソフトウェアエンジニアリングスタックエクスチェンジでそれを聞くことがより望ましいでしょう。コメントをお寄せください。ここから削除します。
ありがとうございます!
あなたの答えをありがとう!私も同じことをやった。 – F3R1