0

在 JSF、EJB 和 JPA 中创建 Web 应用程序时,我们遇到了一个思想问题。

我们的示例情况是:

管理员在数据表中显示用户列表。接下来,他选择 user1,这会将他带到新的用户版站点。如果他尝试打开第二张卡或窗口并在同一会话中选择 user2 进行同时编辑,则会出现此问题。当我们尝试在编辑后保存 user1 数据时,这是不可能的,因为它在 Endpoint 中被 user2 覆盖。

数据存储:因为我们没有在项目的视图部分存储任何数据[下图可用],在显示它之后,托管 Bean 被销毁。因此,在控制器部分,我们决定将当前选择的用户保留为 Endpoint [Stateful EJB Bean] 中的一个字段,该字段对于会话来说是恒定的,因为它由 Session Scoped Managed Bean 持有。我们认为我们不应该在 Endpoint 或 Session Scope Managed Bean 中存储任何集合。

问题:特殊情况是对情况的概述。在我们的应用程序中,我们希望在会话期间编辑多个相同类型的实体。

问题:我们应该在哪里以及如何存储用户/管理员的当前选择,这会导致该选定实体的版本。

在视图中存储数据,请求范围部分允许我们在同一个会话中控制多个实体,尽管我们认为这不是合适的方法。但是现在将其存储在控制器部分会导致限制在同一会话中编辑一个相同类型的实体。

图表在这里:http: //i.stack.imgur.com/9PyYr.jpg

4

2 回答 2

2

因此,您希望学到的教训是不要使用会话范围来编辑数据或在页面之间传输数据。

您应该在这里做的是使用仅包含要编辑的用户 ID 的 GET 请求。然后在编辑页面上,使用单个视图范围的支持 bean。

使用这种模式,您不需要额外的扩展。仅当您使用 CDI bean 作为支持 bean 时才需要 CODI,因为不幸的是默认的 @ViewScoped 不适用于 CDI bean。CODI 提供了一个与 CDI 一起工作的版本。

但是,如果您使用 JSF 托管 bean,请遵循上面概述的模式,您会没事的。

于 2012-07-28T15:14:22.573 回答
1

由于您使用的是 Java EE 服务器(Glassfish 3.1),因此您可以利用支持与 JSF 不同范围的 CDI。有一个名为CODI的 CDI 扩展,它提供所谓的“窗口范围”,允许您为每个浏览器窗口设置 bean 的范围,这将解决您的问题。可以在此处找到有关窗口范围的更多信息。

另一种选择是使用也支持自己的窗口范围的 IceFaces JSF 库。更多信息可以在这里找到。

于 2012-07-27T14:20:19.717 回答