0

我的用例如下:

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

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

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

从带有客户信息、付款信息和订单行列表的订单详细信息视图,用户可以导航到添加/编辑订单行的订单详细信息视图以及以类似方式导航到客户和付款详细信息视图。这些详细视图都使用相同的 OrderControllerBean。在客户、订单行和付款明细视图中,有确定和取消按钮,它们不是事务性的。

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

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

我不确定以下问题:

如果用户从不使用 Save 或 Cancel 会发生什么?

在转换或会话超时之前,一切都会一直存在吗?从交易的角度来看,这意味着什么?这对托管实体意味着什么?如果用户离开他的工作场所并稍后回来继续进行对话会发生什么?如果对话超时,我该如何优雅地处理这个问题?

4

2 回答 2

0

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

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

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

总而言之,在 Web 服务器端将事物分开、超时和临时对象,并将 ejb 用于持久性 (JPA) 和作为外观(无状态 bean)

于 2012-09-13T21:13:06.897 回答
0

为什么在创建订单时需要评估非此即彼的情况?应该有一个按钮,上面写着:启动弹出表单的新订单和另一个可能来自显示“查看订单详细信息”的数据表行。设计很好。只是一些微调。

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