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

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

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

提前谢谢了!

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

这里有一些阅读: JEE6教程 – 会话豆

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

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

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

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

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

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

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

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

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