JPA:哪些实现支持延迟加载外部事务?
Posted
技术标签:
【中文标题】JPA:哪些实现支持延迟加载外部事务?【英文标题】:JPA: which implementations support lazy loading outside transactions? 【发布时间】:2012-04-27 00:25:49 【问题描述】:EclipseLink 可以在实体中加载惰性关系,即使在创建它们的实体管理器不再可用之后也是如此。使用 Hibernate this doesn't work,或者至少在发帖时没有。
其他供应商呢?尤其是 OpenJPA 和 DataNucleus?
这样做有什么缺点(除了更复杂的实现)?
【问题讨论】:
那篇文章提到了关闭数据库连接时的延迟加载。没有提到关闭 EntityManager。一个 EntityManager 可以表示一段时间内的多个连接。 @DataNucleus 见***.com/a/8491416/9204 和forums.oracle.com/forums/thread.jspa?messageID=1706796 当然,但这不是你提到的帖子的内容,也不是你的帖子标题“......外部交易” 【参考方案1】:请注意,Hibernate 4.1.6 添加了对通过 hibernate.enable_lazy_load_no_trans
JPA 属性在事务外部加载惰性数据的支持。
似乎没有被广泛使用/知道 - 唯一的官方文档似乎是 feature ticket - 所以可能值得谨慎使用。
根据我的(有限的)经验,它通常似乎运行良好,只是它似乎没有在双向关系的“映射”端获取实体。
【讨论】:
【参考方案2】:如果您没有 EntityManager,则您不了解数据存储、EMF 或任何东西。所以不,如果你想要便携,你就不能做延迟加载(除了你自己在你的对象中体现该信息)......也就是说,这超出了 JPA 规范。
DataNucleus JPA 可以很好地执行事务之外的字段延迟加载。显然,您需要说明您是使用 TRANSACTION 还是 EXTENDED persistence context 运行,因为在前一种情况下,对象在事务提交时被 DETACHED(一旦分离就不能延迟加载),而在后者中,对象仍然是 MANAGED 的(在这种情况下你可以延迟加载)。
【讨论】:
【参考方案3】:虽然 Hibernate 确实需要相同的 EntityManager 才能延迟加载对象,但使用 Open Session in View Pattern 很容易实现灵活的延迟加载。本质上,只要需要,您就可以保持 EntityManager 处于打开状态。我开发了客户端应用程序,只要应用程序打开,它就会保持相同的 EntityManager 打开。这将为您提供与文章中描述的基本相同的行为。但是,实现起来肯定比 Roman 所描述的“开箱即用”延迟加载更难实现。
话虽如此,there are downsides to lazy loading。开发人员必须了解他的获取策略,并且必须能够区分每种策略最适用的时间和地点。否则,您可能会遇到严重的性能问题,例如 N+1 Select Problem。另外,在呈现视图期间,您总是有可能遇到数据库异常。
关于 OpenJPA 和 DataNucleus:虽然我从来没有使用过,this post 表示 OpenJPA 还需要 OpenSessionInViewFilter
用于延迟加载。 This SO answer 和 this forum post 表示 DataNucleus 需要 OpenPersistenceManagerInViewFilter
才能延迟加载。
【讨论】:
以上是关于JPA:哪些实现支持延迟加载外部事务?的主要内容,如果未能解决你的问题,请参考以下文章