我有一个企业应用程序(至少)有一个 Web 层(仅 UI)和一个服务层。服务层中的所有业务逻辑和当前对话状态均以 @Stateful @LocalBean
EJB(无 CDI)的形式实现。
就 CDI 而言,这有点类似于 @SessionScoped
bean,对吗?
所以,问题来了:
我在 Web 层 (@Named @ConversationScoped
) 中有一个长时间运行的对话,并且想要访问有状态 EJB。应该在该 session 的不同 Controller (bean)中访问 EJB。我不能这样做:@EJB
因为它将是特定 EJB 类型的不同实例。我必须以某种方式保存对 EJB 的引用。这是我当前的解决方案:
@EJB
private MyEJB _myEJB; // a stateful EJB
@Produces
@Builder // custom quallifier
@ConversationScoped
public MyEJB produceMyEJB() {
return _myEJB;
}
现在我可以在每个 session 范围 Controller 中访问有状态 EJB 的相同实例,如下所示 @Inject @Builder MyEJB _myEJB
。
大多数时候它都有效。但在一些长时间运行的测试中,此引用为空,我不知道为什么。
我在 Glassfish 的 server.log 中得到了这个堆栈跟踪:
javax.ejb.NoSuchObjectLocalException: The EJB does not exist. session-key:
907f0200001f-ffffffffc3388fbb-761
和/或
Cannot load from BACKUPSTORE FOR Key: <907f0200001f-ffffffffc3388fbb-761>
您知道为什么会发生这种情况吗?感谢您的帮助,并对我的英语不好表示歉意。
最佳答案
您的有状态 EJB 可能超时。查看javax.ejb.StatefulTimeout
:http://docs.oracle.com/javaee/6/api/javax/ejb/StatefulTimeout.html
@Stateful
@StatefulTimeout(unit = TimeUnit.MINUTES, value = 30)
public class MyEJB {
关于java - 业务层中的有状态 EJB 用于 Web 层的 session 范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9537652/