EJB 自我调用和自我注入

EJB self invocation and self inject

我有一个更可能是关于 EJB 和自调用和事务的理论和软件设计问题。

假设我有一个 EJB class,我在其中使用也在该 EJB 中的另一个方法调用其中一个 EJB-s 方法。但是我想按顺序在第二种方法中使用事务注释功能。所以更具体地说:

@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 注释的自我注入 我将 bean 注入自身并调用注释方法。 2. 我可以使用 JNDI,它有点旧但很好。 3. 我可以使用当前示例中的 SessionContextgetBusinessObject 方法。 4. 我可以创建另一个 EJB 并将这个带注释的方法放在那里。

我的问题是在软件设计和简洁代码方面哪个更好?因为我知道自注入不是一个好方法,JNDI 很旧,但是 SessionContext 解决方案也是基于 JNDI 的,如果我将方法分离到另一个 EJB 中,我只是牺牲应用程序的 OOP 设计来使用干净的 EJB 技术。 .那么在这种情况下推荐的解决方案是什么?感谢您的提前!如果这个问题是 Whosebug 的理论问题,最好在 Software Engineering Stack Exchange 上提问,请随时发表评论,我会从这里删除它。

提前致谢!

我总是使用 SessionContext。在@PostConstruct 中,我调用sessionContext.getBusinessObject 并设置一个名为'self' 的成员变量。然后,当我需要调用本地方法时,我使用 'self.someMethod()'.

注意我只在需要单独的事务或想异步调用该方法时才这样做。