我想知道在 Hibernate/JPA 世界中处理接受输入的数据表的正确方法是什么。据我所知,以下三个选择之一导致整个纸牌屋分崩离析,但我不知道哪个是错误的。
- 通过自定义 JSF PhaseListener 进行半自动事务和 EntityManager 处理,围绕每个请求开始并提交事务
- 将编辑组件放在数据表中
- 使用请求范围内的托管 bean 从请求范围内的 EntityManager 中获取数据(在 PrettyFaces 的帮助下从它们的 URL 为请求范围内的 bean 设置 ID)
- 使用请求范围的 bean 而不是 View 或 session 范围的 bean 支持数据表。
我看到 an ICEfaces dataTable demo using JPA但它们都是手动管理事务,默认情况下不显示编辑组件。您单击导致对象被指定为可编辑性的行,然后当您点击“保存”时,它会在手动触发保存之前手动将对象重新连接到新的 EntityManager。我看到这里的点击编辑功能为我们提供了一种方法来确保将正确的对象重新附加到当前 session ,我不知道如果没有类似的东西,人们将如何生活。
我对新的 ICEfaces 3.0 ace:dataTable(née PrimeFaces 2.0 dataTable)的印象是它旨在用于 View- 或 Session-scoped bean,但我不明白怎么可能绕过 StaleObjectState 和/或 LazyInitializationExceptions,如果一个模型对象在请求 A 和 EntityManager A 中来自 DAO,然后被带有 EntityManager B 的请求 B 修改或调入。
我想它可能会通过某种深入的研究在 Java EE 下工作,但我现在没有将我们从 Tomcat 6 升级到任何更高级的东西的奢侈(尽管从长远来看这是我的意图)。我们也不打算开始使用 Spring 或 Seam 或任何其他很酷的东西。 ICEfaces 对我们来说已经够奇怪了,老实说可能太奇怪了。
所以综上所述,以下哪个是错误的选择?请求范围的实体管理器、请求范围的数据表或在数据表中使用编辑组件?或者这里真的有其他问题?
最佳答案
如果您问我,主要的错误似乎是当您的要求似乎尖叫着想要一些更高级的东西时,却坚持使用几乎裸露的 Tomcat。口头禅通常是当您不需要“所有其他东西”时使用 Tomcat,所以当您确实需要它时,为什么还要继续使用裸 Tomcat?
也就是说,这个模式真的没有那么难。
- 有一个 View 范围的辅助 bean
- 在
@PostConstruct
中获取初始数据-(当没有ID等参数时)或PreRenderViewEvent
方法结合 View 参数 - 使用单独的服务类,使用实体管理器来获取和保存数据
- 使实体管理器成为“事务范围”
- 没有 EJB/CDI/Spring:
- 为每个操作从实体管理器工厂获取新的实体管理器。
- 启动(资源本地)事务,执行操作,提交事务,关闭实体管理器。
- 没有 EJB/CDI/Spring:
- 直接从您的支持 bean 返回实体列表,将表的编辑模式输入字段绑定(bind)到实体的相应属性。
- 更新单行时,将相应的实体传递给服务的更新方法。除了获取实体管理器、启动事务等的开销之外,这基本上只调用实体管理器上的
merge()
。
意识到在服务之外,您一直在使用分离的实体
。因此没有任何 LazyInitializationExceptions 的风险。支持 bean 需要在 View 范围内,以便 JSF 更新正确的(分离的!)实体,然后您自己的代码将其传递给服务,服务将其合并到持久性上下文中。
因此持久化的流程是:
View state View scope Transaction scoped PC Facelet/components Backing Bean Service Strings ------> Detached entities --> Attached entities
(获取数据的流程正好相反)
虽然以这种方式创建服务有点乏味,但也是一种受虐狂练习。对于一个示例应用程序和上面讨论的两种方法(获取和更新),它不会那么糟糕,但对于任何规模较大的应用程序,这将很快失去控制。
如果您已经将 JSF 和 JPA 添加到 Tomcat,请帮自己一个忙,使用类似 TomEE 的东西.这几乎不比 Tomcat 大(25MB 对 7MB),并且包含您应该试图避免但实际上无论如何都需要的所有内容。
如果您绝对无法升级您的 Tomcat 安装(例如,产品所有者或经理认为他拥有服务器而不是开发人员),您可能需要投资学习 CDI。这可以很容易地添加到您的 war 中(只需一个额外的 jar ),让您抽象出许多乏味的代码。您还可以真正使用的一件事是 JTA 提供程序。这也可以单独添加到您的 war 中,但是您添加的这些东西越多,您只需使用 TomEE(或 GlassFish、Resin、JBoss 等替代品)就越好。
另请参阅这篇文章,其中涵盖了您要求的各个部分:Communication in JSF 2.0
关于jsf-2 - 集成 ice/ace :dataTable with JPA and request-scoped beans,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9285774/