Jakarta ee EJB自调用和自注入
关于EJB-s、自调用和事务,我有一个更可能的理论和软件设计问题 假设我有一个EJB类,在这个类中,我用另一个方法调用一个EJB-s方法,这个方法也在这个EJB中。但我想在第二种方法中依次使用事务注释特性。更具体地说:Jakarta ee EJB自调用和自注入,jakarta-ee,transactions,ejb,self-reference,Jakarta Ee,Transactions,Ejb,Self Reference,关于EJB-s、自调用和事务,我有一个更可能的理论和软件设计问题 假设我有一个EJB类,在这个类中,我用另一个方法调用一个EJB-s方法,这个方法也在这个EJB中。但我想在第二种方法中依次使用事务注释特性。更具体地说: @Local(BorrowingService.class) @Stateless public class BorrowingServiceBean implements BorrowingService { static final JcanLogger LOG =
@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.");
}
}
}
@Local(借用服务.class)
@无国籍
公共类BorrowingServiceBean实现了BorrowingService{
静态最终JcanLogger日志=JcanLogger工厂
.getLogger(借用ServiceBean.class);
@PersistenceContext(unitName=ApplicationConstants.PERSISTENCE\u UNIT\u NAME)
受保护的实体管理器em;
@资源
非公开会话上下文会话上下文;
@EJB
私人私人服务;
@EJB
私有StatusBean StatusBean;
@EJB
私人图书服务;
私人静态最终长期无原因回报成本=5;
已检查私有静态最终字符串\u ISBN=“0201104040”;
公共静态最终长人账户扣减=10;
@凌驾
public void returnBook(长bookId、长userId){
if(bookId==null | | userId==null){
抛出新的IllegalArgumentException(“bookId和userId不能为null”);
}
List BorrowingByUserId=GetBorrowingByUserId(userId);
for(借用性借用性借用性:借用BYUSERID){
BookEntity tmpBook=brookingEntity.getBook();
if(tmpBook.getBookId().equals(bookId)){
em.remove(借用性);
打破
}
}
//推荐的自我调用可能在这里
onBookReturn(userId,bookId);
}
/**
*旨在在新事务中运行后处理方法(不应从此处删除,应保持原样)。
*意图:db change后跟异常表示出于某种原因应该回滚的一些操作。
*/
@TransactionAttribute(TransactionAttributeType.REQUIRES\u NEW)
@凌驾
public void onBookReturn(长userId,长bookId){
BookEntity book=bookService.getBookById(bookId);
如果(已选中\u ISBN.equals(book.getIsbnNumber())){
personService.decreasePersonAccount(用户ID、无原因返回成本);
抛出新的InvalidOperationException(“尝试了一个不应该执行的操作。应该回滚此更改”);
}
}
}
我知道对于这种情况有一些解决办法。
1.我可以将自注入与@EJB
注释结合使用,我将bean注入自身并调用带注释的方法。
2.我可以使用JNDI,它有点旧,但很好。
3.我可以使用当前示例中的SessionContext
的getBusinessObject
方法。
4.我可以创建另一个EJB并将这个带注释的方法放在那里
我的问题是在软件设计和干净的代码方面,哪个更好?因为我知道自注入不是一种好方法,JNDI很旧,但SessionContext解决方案也基于JNDI,如果我将该方法分离到另一个EJB中,我只会牺牲应用程序的OOP设计来使用EJB技术。。。那么,在这种情况下,推荐的解决方案是什么?谢谢你的进步!如果这个问题对于Stackoverflow来说是理论性的,并且最好在软件工程堆栈交换上问它,请随意评论,我将从这里删除它
提前谢谢 我总是使用SessionContext。在@PostConstruct中,我调用sessionContext.getBusinessObject并设置名为“self”的成员变量。然后,当我需要调用本地方法时,我使用“self.someMethod()” 注意,我只在需要单独的事务或希望异步调用该方法时才这样做