我有一个企业应用程序(至少)有一个Web层(仅限UI)和一个服务层。在服务层中,所有业务逻辑和当前会话状态都实现为@Stateful @LocalBean
EJB(无CDI)。
就CDI而言,这有点类似于@SessionScoped
bean,对吗?
所以,这是问题所在:
我在Web层(@Named @ConversationScoped
)中有一个长时间运行的对话,并且想要访问有状态EJB。应该在此对话的不同控制器(bean)中访问EJB。我不能这样做:@EJB
因为它将是特定EJB类型的不同实例。我必须以某种方式保存对EJB的引用。这是我目前的解决方案:
@EJB
private MyEJB _myEJB; // a stateful EJB
@Produces
@Builder // custom quallifier
@ConversationScoped
public MyEJB produceMyEJB() {
return _myEJB;
}
现在,我可以在每个会话作用域控制器中访问相同的有状态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>
你有任何想法为什么会这样吗?感谢您的帮助,抱歉我的英语不好。
答案 0 :(得分:1)
您的有状态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 {