3

我想知道在 Hibernate/JPA 世界中处理数据表的正确方法是什么。据我所知,以下三个选择之一是导致整个纸牌屋分崩离析,但我不知道哪个是错误的。

  • 通过自定义 JSF PhaseListener 进行半自动事务和 EntityManager 处理,该 PhaseListener 围绕每个请求开始并提交事务
  • 将编辑组件放入数据表中
  • 使用从请求范围的 EntityManager 获取数据的请求范围的托管 bean(在 PrettyFaces 的帮助下从其 URL 中设置请求范围的 bean 的 ID)
  • 使用请求范围的 bean 而不是视图或会话范围的 bean 支持 dataTable。

我看到一个使用 JPA 的 ICEfaces dataTable 演示,但它们都是手动管理事务并且默认情况下不显示编辑组件。您单击导致对象被提名为可编辑的行,然后当您点击“保存”时,它会在手动触发保存之前手动将对象重新连接到新的 EntityManager。我认为这里的点击编辑功能为我们提供了一种方法来确保将正确的对象重新附加到当前会话,我不知道如果没有类似的东西将如何生活。

我对新的 ICEfaces 3.0 ace:dataTable (née PrimeFaces 2.0 dataTable) 的印象是它旨在用于视图或会话范围的 bean,但我不明白如何绕过 StaleObjectState和/或 LazyInitializationExceptions,如果一个模型对象从请求 A 和 EntityManager A 中的 DAO 出来,然后被请求 B 和 EntityManager B 修改或分页。

我想它可能通过某种深度的 fu 在 Java EE 下工作,但我现在没有将我们从 Tomcat 6 升级到更高级的东西的奢侈(尽管从长远来看这是我的意图)。我们也不打算开始使用 Spring 或 Seam 或任何其他很酷的东西。ICEfaces 对我们来说已经够奇怪了,说实话可能太奇怪了。

综上所述,这些中哪个是错误的选择?请求范围的实体管理器、请求范围的数据表还是在数据表中使用编辑组件?还是这里真的有其他问题?

4

1 回答 1

4

如果您要问我,主要的错误似乎是坚持使用几乎光秃秃的 Tomcat,而您的要求似乎要求更高级的东西。口头禅通常是当您不需要“所有其他东西”时使用 Tomcat,所以当您确实需要它时,为什么继续使用裸 Tomcat?

也就是说,这个模式真的没有那么难。

  • 有一个视图范围的支持 bean
  • 结合视图参数获取@PostConstruct-(当没有ID等参数时)或方法中的初始数据PreRenderViewEvent
  • 使用使用实体管理器获取和保存数据的单独服务类
  • 使实体管理器“事务范围”
    • 没有 EJB/CDI/Spring:
      • 从实体管理器工厂为每个操作获取一个新的实体管理器。
      • 启动(资源本地)事务,执行操作,提交事务,关闭实体管理器。
  • 直接从您的支持 bean 返回实体列表,将表的编辑模式输入字段绑定到实体的相应属性。
  • 更新单行时,将相应的实体传递给服务的更新方法。除了获取实体管理器、启动事务等的开销之外,这基本上只调用merge()实体管理器。

意识到您一直在使用的服务之外detached entities。因此没有任何 LazyInitializationExceptions 的风险。支持 bean 需要在视图范围内,以便正确的(分离的!)实体由 JSF 更新,然后您自己的代码将其传递给服务,该服务将其合并到持久性上下文中。

因此,持久化的流程是:

查看状态               查看范围        事务范围 PC 
Facelet/组件       支持 Bean       服务
      字符串 ------> 分离实体 --> 附加实体

(获取数据的流程正好相反)

以这种方式创建服务有点乏味,而且是一种受虐狂的练习。对于一个示例应用程序和上面讨论的两种方法(获取和更新)来说,它不会那么糟糕,但对于任何大型应用程序来说,这将很快失控。

如果您已经将 JSF 和 JPA 添加到 Tomcat,请帮自己一个忙并使用TomEE 之类的东西。这仅比 Tomcat 大(25MB 对 7MB),并且包含了所有你应该试图避免但实际上仍然需要的东西。

如果您绝对无法升级 Tomcat 安装(例如,产品所有者或经理认为他拥有服务器而不是开发人员),您可能需要投资学习 CDI。这可以很容易地添加到您的战争中(只需一个额外的 jar),让您抽象出许多繁琐的代码。您还可以真正使用的一件事是 JTA 提供程序。这也可以单独添加到您的战争中,但是您添加的这些东西越多,仅使用 TomEE(或 GlassFish、Resin、JBoss 等替代品)就越好。

另请参阅这篇文章,它涵盖了您需求的各个部分:JSF 2.0 中的通信

于 2012-02-19T11:43:06.690 回答