EJB3 / JSF2:使用ConversationalScope和Stateful EJB设计JSF2应用程序

时间:2012-09-13 20:55:01

标签: jsf-2 ejb-3.0 java-ee-6

我的用例如下:

使用订单行,客户和付款详细信息管理订单。

该应用程序包含一个订单列表视图,可以从中打开订单详细信息视图以编辑现有订单或创建新订单。订单详细信息视图使用视图参数(现有订单ID或无任何内容来指示要创建的新订单)。

当订单详细信息视图打开时,OrderControllerBean正在启动ConversationalScope,具体取决于订单ID加载或创建新订单实体的可用性。这个bean是一个有状态会话bean,也可以用作外观。 bean包含处理订单行,客户和付款细节以及保存和删除订单的方法。这些方法使用注入的EJB作为无状态会话bean,作为处理JPA实体订单,订单行,客户和付款细节的某种DAO。

在包含客户信息,付款信息和订单行列表的订单详细信息视图中,用户可以以类似方式导航到订单行详细信息视图添加/编辑订单行以及客户和付款详细信息视图。这些详细视图都使用相同的OrderControllerBean。在客户,订单行和付款明细视图上,有“确认”和“取消”按钮,这些按钮不是交易性的。

在订单详细信息视图中,有一个“保存并取消”按钮,该按钮应保留在会话期间完成的所有修改。

我现在的问题是:这个设计合适吗?

我不确定以下问题:

如果用户从不使用保存或取消,会发生什么?

一切都待在转换或会话超时之前? 从交易角度来看,这意味着什么? 这对管理实体意味着什么? 如果用户离开他的工作场所并在以后继续处理对话时会发生什么?如果对话超时,我怎样才能优雅地处理这个问题?

2 个答案:

答案 0 :(得分:0)

在我看来,有状态的豆是一种痛苦和问题的根源。

最好是在http会话级别处理超时,而不是将此责任交给应用程序服务器(特别是因为http会话超时仍然相关,你只需添加另一个超时)

您可以使用某种对象缓存替换有状态bean提供的persitent状态,或者如果您愿意,可以将sessionid添加到数据库并跟踪对象状态(它可以是用于保存临时对象的特殊表)直到保存或丢弃为例)。

总而言之,在Web服务器端保持分离,超时和临时对象,并使用ejbs进行持久化(JPA)和作为外观(无状态bean)

答案 1 :(得分:0)

为什么需要评估创建订单的任何一种情况?应该只有一个按钮,上面写着:新订单,用于启动弹出窗体和另一个,可能来自显示“查看订单详细信息”的数据表行。 设计很好。只是做了一些调整。

  1. 您需要创建和维护一个会话范围对象(称为Visit),您可以在其中存储所有与会话相关的资料。我建议你坚持使用依赖于http会话的JSF会话作用域bean,并且可以由容器进行有效管理。 JSF Session Scoped bean作为简单对象存储在http会话中,因此可以在JSF的上下文之外轻松操作。然而,CDI Session Scoped bean在CDI之外处理起来比较棘手。
  2. 我还建议您使用动态加载的页面片段<ui:include/>或精细的 primefaces向导组件将您的订单创建过程分解为多步骤过程。通过多步创建,您需要做的就是沿着步骤收集数据,并且只有在您从DTO中的所有步骤获得所需的所有信息时才提交事务。将向导DTO保留在单个会话对象中,以便容器可以在超时的情况下进行清理。如果用户从未保存或取消或离开他的办公桌,会话将自然死亡。如果他能及时完成,他可以回来继续他的交易。不确定carlos对无状态会话bean的反对意见,但根据我的经验,它们是暴露业务流程的一种很好的方式,因为它们可以通过其他方式公开其功能,如Web服务和消息目标(JEE5) 。 最重要的是,将尽可能多的业务处理从托管bean中保留到EJB和Spring bean等持久构造中是非常好的设计。