JPA:扩展持久化上下文与分离实体

mer*_*ike 11 java hibernate jpa-2.0

似乎有两种模式可以实现跨越几个带有JPA的http请求的业务事务:

  1. 具有分离实体的每个请求的实体管理器
  2. 扩展持久化上下文

这些模式各自的优势是什么?何时应该优先考虑?

到目前为止,我想出了:

  • 扩展的持久化上下文保证对象标识等同于数据库标识,简化了编程模型,并可能消除了为实体实现equals的需要
  • 分离的实体比扩展的持久性上下文需要更少的内存,因为持久性上下文还必须存储实体的先前状态以进行更改检测
  • 不再引用的分离实体有资格进行垃圾回收; 必须首先明确地分离持久对象

但是,没有任何JPA的实践经验我相信我已经错过了一些重要的东西,因此这个问题.

如果重要:我们打算使用Hibernate 3.6支持的JPA 2.0.

编辑:我们的视图技术是JSF 2.0,在EJB 3.1容器中,带有CDI,可能还有Seam 3.

Aff*_*ffe 18

好吧,我可以通过尝试在Web环境中使用扩展持久性上下文来列举挑战.有些事情还取决于您的视图技术是什么,以及它是绑定实体还是视图级别的中间人.

  1. EntityManagers不是线程安全的.每个用户会话不需要一个.每个浏览器选项卡每个用户会话需要一个.
  2. 当EntityManager出现异常时,它被视为无效,需要关闭和替换.如果您计划编写自己的框架扩展来管理扩展生命周期,那么实现它需要是防弹的.通常在EM-per-request设置中,异常会转到某种错误页面,然后加载下一页就会像往常一样创建一个新页面.
  3. 对象平等不会100%自动安全.如上所述,异常可能使先前加载的对象与之关联的上下文无效,因此现在提取的对象将不相等.做出这个假设还假设了一个非常高水平的技能和理解JPA如何工作以及EM在使用它的开发人员中做了什么.例如,在不需要时意外使用合并将返回一个新对象,该对象不满足==与其字段相同的前任.(像SQL'更新'一样处理合并是一个非常常见的JPA noobie'错误',特别是因为它大部分时间只是一个无操作,所以它滑过了.)
  4. 如果您正在使用绑定POJO的视图技术(例如,SpringMVC)并且您计划将Web表单数据直接绑定到您的实体上,那么您将很快遇到麻烦.对附加实体的更改将在下一次刷新/提交时变为持久性,无论它们是否在事务中完成.常见错误是,Web表单进入并将一些无效数据绑定到实体上,验证失败并尝试返回屏幕以通知用户.构建错误屏幕涉及运行查询.查询触发持久化上下文的刷新/提交.绑定到附加实体的更改将刷新到数据库,希望导致SQL异常,但可能只是持久存在损坏的数据.

(如果编程很草率,问题4当然也可以在每个请求的会话中发生,但是你没有被迫积极努力避免它.)