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. 我可以使用当前示例中的 SessionContext
的 getBusinessObject
方法。
4. 我可以创建另一个 EJB 并将这个带注释的方法放在那里。
我的问题是在软件设计和简洁代码方面哪个更好?因为我知道自注入不是一个好方法,JNDI 很旧,但是 SessionContext 解决方案也是基于 JNDI 的,如果我将方法分离到另一个 EJB 中,我只是牺牲应用程序的 OOP 设计来使用干净的 EJB 技术。 .那么在这种情况下推荐的解决方案是什么?感谢您的提前!如果这个问题是 Whosebug 的理论问题,最好在 Software Engineering Stack Exchange 上提问,请随时发表评论,我会从这里删除它。
提前致谢!
我总是使用 SessionContext。在@PostConstruct 中,我调用sessionContext.getBusinessObject 并设置一个名为'self' 的成员变量。然后,当我需要调用本地方法时,我使用 'self.someMethod()'.
注意我只在需要单独的事务或想异步调用该方法时才这样做。
我有一个更可能是关于 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. 我可以使用当前示例中的 SessionContext
的 getBusinessObject
方法。
4. 我可以创建另一个 EJB 并将这个带注释的方法放在那里。
我的问题是在软件设计和简洁代码方面哪个更好?因为我知道自注入不是一个好方法,JNDI 很旧,但是 SessionContext 解决方案也是基于 JNDI 的,如果我将方法分离到另一个 EJB 中,我只是牺牲应用程序的 OOP 设计来使用干净的 EJB 技术。 .那么在这种情况下推荐的解决方案是什么?感谢您的提前!如果这个问题是 Whosebug 的理论问题,最好在 Software Engineering Stack Exchange 上提问,请随时发表评论,我会从这里删除它。
提前致谢!
我总是使用 SessionContext。在@PostConstruct 中,我调用sessionContext.getBusinessObject 并设置一个名为'self' 的成员变量。然后,当我需要调用本地方法时,我使用 'self.someMethod()'.
注意我只在需要单独的事务或想异步调用该方法时才这样做。