Java EE 6:如何从无状态会话Bean调用有状态会话Bean?

时间:2012-07-11 16:30:32

标签: java ejb stateless-session-bean stateful-session-bean

我有一个状态会话Bean(SFSB),它充当身份验证模块。在SFSB中,我存储了当前登录的用户。此外,我还有一些外观(无状态会话Bean(SLSB))处理我的实体的JPA / SQL内容。为了检查当前用户的访问权限,我尝试从SLSB中调用SFSB。但是当从SLSB调用时,当前用户字段始终为“null”。直接调用SFSB时,当前用户字段设置正确...对于调用我使用@EJB注释。

任何想法可能是什么问题?这是某种上下文问题吗?通常是否可以从SLSB调用SFSB来保留它的状态?

非常感谢提前!

3 个答案:

答案 0 :(得分:8)

您不应该从无状态会话bean调用有状态会话bean。

以下是一些阅读:JEE6 Tutorial - Session Beans

无状态bean对您的会话一无所知。无论何时你打电话,它都是无国籍的。然后它调用有状态会话bean。毫不奇怪,它没有任何与客户端会话状态相关的上下文,因为它是从无状态对象调用的。

我不知道它是否会起作用,但你可能会尝试通过使用@EJB表示法进行JNDI查找而不是DI来获取上下文。无状态ejb中的这样的东西可能会起作用。你可能不得不玩它,我无法保证任何东西。它应该获取客户端调用无状态ejb的上下文。客户端需要具有会话上下文/范围或忘记它。

@Resource SessionContext sessionContext;

MyStatefulBean msb = (MyStatefulBean)sessionContext.lookup("ejb/MyStatefulBean");
msb.doSomething(fubar);

最好从具有会话范围的客户端或其他有状态ejb调用有状态会话bean。无国籍和有状态有不同的理由。

答案 1 :(得分:4)

您不应该将有状态EJB注入无状态EJB。这可能会产生非常不可预测的后果,因为有状态EJB的生命周期是在拥有bean注入和管理时启动的。在最坏的情况下,应用程序服务器可以为不同的用户重用无状态EJB,然后这些用户将访问相同的有状态EJB。在您的情况下,用户将被识别为不同的用户。

最有可能的是,您希望将有状态EJB与当前的HTTP会话相关联,而这并不像许多人想象的那样自动完成。有关更多详细信息,请在此处阅读名为EJB 3 Is Not Contextual的部分:Contexts and Dependency Injection article

为了将有状态EJB与会话相关联,您需要将有状态EJB注入会话范围的CDI bean,它可以自由地注入无状态bean - 实际上只注入了一个存根和会话范围的bean(与为每个新会话创建有状态EJB。

也许更好的方法是提取有状态bean的接口,并使用CDI生成器来创建sateful bean的会话范围实现。这样,当EJB中的异常自动删除有状态EJB时,您也可以处理这种情况。在这种情况下,您可能希望在同一会话中重新创建EJB。

答案 2 :(得分:0)

如果通过查找在无状态bean中注入有状态会话bean也不起作用,因为将为有状态bean创建新实例,因此它不包含任何值,如已记录的用户信息等...