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:哪些实现支持延迟加载外部事务?的主要内容,如果未能解决你的问题,请参考以下文章

Jpa/Hibernate 字节码增强:字段延迟加载

延迟加载 Spring Data JPA 存储库

延迟加载外部js文件,延迟加载图片(jquery.lazyload.js和echo,js)

MyBatis一对多查询及延迟加载

JPA 延迟加载

在 Hibernate / JPA 2.1 中延迟加载的 @OneToOne 映射不起作用?