【问题标题】:Stateful EJB in business tier used in the conversation scope of the web tier业务层的有状态 EJB 用于 Web 层的会话范围
【发布时间】:2012-03-02 17:25:27
【问题描述】:

我有一个企业应用程序(至少)有一个 Web 层(仅 UI)和一个服务层。服务层是所有业务逻辑和当前会话状态,以@Stateful @LocalBean EJB(无 CDI)实现。

就 CDI 而言,这有点类似于 @SessionScoped bean,对吧?

那么,问题来了: 我在 Web 层 (@Named @ConversationScoped) 进行了长时间的对话,并且想要访问有状态的 EJB。 EJB 应该在这个会话的不同控制器(bean)中被访问。我不能这样做:@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>

您知道为什么会发生这种情况吗?感谢您的帮助,并为我的英语不好感到抱歉。

【问题讨论】:

    标签: java jsf glassfish ejb cdi


    【解决方案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 {
    

    【讨论】:

    • 您好,非常感谢您的回答。但是 EJB 上没有这样的 StatefulTimeout 注释。我发现此超时(删除未使用的 EJB)的默认配置是 90 分钟(通过 localhost:4848 查看 EJB 容器设置)。这比 web.xml 中的会话超时(和对话)要多得多。我错过了什么吗?
    • 您可以使用@StatefulTimeout 注释为特定EJB 设置超时,如我的示例(Java EE 标准)所示。如果要更改所有有状态会话 bean 的默认值,那是特定于服务器的。我不使用 Glassfish,但 glassfish-ejb-jar.xml 中的删除超时时间属性可能是您正在寻找的:docs.oracle.com/cd/E18930_01/html/821-2417/beaqm.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-23
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多