8

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

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

提前谢谢了!

4

3 回答 3

9

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

这是一些阅读:JEE6 教程 - 会话 Bean

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

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

@Resource SessionContext sessionContext;

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

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

于 2012-07-11T17:38:21.170 回答
5

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

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

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

也许更好的方法是提取有状态 bean 的接口,并使用 CDI 生产者创建有状态 bean 的会话范围实现。通过这种方式,您还可以处理有状态 EJB 因 EJB 中的异常而被自动删除的情况。在这种情况下,您可能希望在同一会话中重新创建 EJB。

于 2014-09-15T20:16:36.600 回答
0

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

于 2013-06-07T03:03:12.440 回答