JPA:哪些实现支持在事务外进行延迟加载?

14

EclipseLink可以在实体管理器不再可用的情况下加载实体中的延迟关系。而Hibernate则无法做到这一点,至少在该文章发布时是如此。

其他提供者呢?特别是OpenJPA和DataNucleus?

除了更复杂的实现外,这种方法有哪些缺点?


1
那篇文章提到了在关闭数据库连接时进行惰性加载。并没有提到关闭EntityManager。EntityManager可以在一段时间内代表多个连接。 - DataNucleus
@DataNucleus 请参考 https://dev59.com/YV7Va4cB1Zd3GeqPHz-j#8491416 和 https://forums.oracle.com/forums/thread.jspa?messageID=1706796。 - Alexey Romanov
当然,但这不是您所提到的帖子的主题,也不是您在此处发布的帖子标题“...外部交易”。 - DataNucleus
3个回答

13
虽然Hibernate需要相同的EntityManager才能进行惰性加载对象,但使用Open Session in View Pattern可以轻松实现灵活的惰性加载。实质上,您可以在需要时保持EntityManager处于打开状态。我曾经开发过客户端应用程序,将同一EntityManager保持打开状态,只要应用程序打开即可。这将为您提供与文章中描述的基本相同的行为。但是,它肯定比Roman所描述的“开箱即用”的惰性加载更难实现。
话虽如此,惰性加载也有缺点。开发人员必须了解其提取策略,并能够区分何时和何处适用每种策略。否则,您可能会遇到严重的性能问题,例如N + 1 Select Problem。此外,在视图呈现期间仍有可能出现数据库异常。
关于 OpenJPA 和 DataNucleus:虽然我从未使用过任何一个,但 这篇帖子 指出,OpenJPA 也需要一个 OpenSessionInViewFilter 来进行延迟加载。这个SO回答这篇论坛帖子 则指出,DataNucleus 需要一个 OpenPersistenceManagerInViewFilter 来进行延迟加载。

8
请注意,Hibernate 4.1.6添加了对通过JPA属性hibernate.enable_lazy_load_no_trans在事务外加载惰性数据的支持。
似乎并不是很广泛使用/知道-唯一官方文档似乎是一个功能票-所以可能值得谨慎使用。
根据我的(有限)经验,它通常运行良好,但似乎无法获取双向关系“映射”侧的实体。

5
如果你没有EntityManager,那么你对数据存储、 EMF 或任何其他东西都没有了解。因此,如果你想要可移植性,除非将该信息自己包含在对象中,否则不能进行延迟加载。也就是说,这超出了JPA规范。

DataNucleus JPA 可以很好地在事务之外执行字段的延迟加载。显然,你需要说明你是否使用 TRANSACTION 或 EXTENDED 持久上下文,因为在前一种情况下,对象在事务提交时会变成 DETACHED(分离状态),而此时不能进行延迟加载;而在后一种情况下,对象保持为 MANAGED(托管状态),在此情况下,可以进行延迟加载。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接