业务层中的有状态EJB,用于Web层的对话范围

时间:2012-03-02 17:25:28

标签: java jsf glassfish ejb cdi

我有一个企业应用程序(至少)有一个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>

你有任何想法为什么会这样吗?感谢您的帮助,抱歉我的英语不好。

1 个答案:

答案 0 :(得分:1)

您的有状态EJB可能已超时。查看javax.ejb.StatefulTimeouthttp://docs.oracle.com/javaee/6/api/javax/ejb/StatefulTimeout.html

@Stateful
@StatefulTimeout(unit = TimeUnit.MINUTES, value = 30)
public class MyEJB {