EclipseLink 可以在实体中加载惰性关系,即使在创建它们的实体管理器不再可用之后也是如此。对于 Hibernate ,这不起作用,或者至少在那篇文章的时候没有。
其他供应商呢?特别是 OpenJPA 和 DataNucleus?
这有什么缺点(除了更复杂的实现)?
EclipseLink 可以在实体中加载惰性关系,即使在创建它们的实体管理器不再可用之后也是如此。对于 Hibernate ,这不起作用,或者至少在那篇文章的时候没有。
其他供应商呢?特别是 OpenJPA 和 DataNucleus?
这有什么缺点(除了更复杂的实现)?
尽管 Hibernate 确实需要相同的 EntityManager 才能延迟加载对象,但使用Open Session in View Pattern很容易实现灵活的延迟加载。本质上,只要需要,您就可以保持 EntityManager 处于打开状态。我开发了客户端应用程序,只要应用程序处于打开状态,它们就会保持相同的 EntityManager 处于打开状态。这将为您提供与文章中描述的基本相同的行为。但是,它肯定比 Roman 描述的“开箱即用”延迟加载更难实现。
话虽如此,延迟加载也有缺点。开发人员必须了解他的获取策略,并且必须能够区分每种策略最适用的时间和地点。否则,您可能会遇到严重的性能问题,例如N+1 Select Problem。另外,在呈现视图期间,您总是有可能遇到数据库异常。
关于 OpenJPA 和 DataNucleus:虽然我从未使用过,但这篇文章表明 OpenJPA 也需要OpenSessionInViewFilter
延迟加载。这个 SO 答案和这个论坛帖子表明 DataNucleus 需要OpenPersistenceManagerInViewFilter
延迟加载。
请注意,Hibernate 4.1.6 添加了对通过hibernate.enable_lazy_load_no_trans
JPA 属性在事务外部加载惰性数据的支持。
似乎没有被广泛使用/知道 - 唯一的官方文档似乎是一张功能票- 所以可能值得谨慎使用。
在我(有限的)经验中,它通常似乎运行良好,只是它似乎没有在双向关系的“映射”端获取实体。
如果您没有 EntityManager,则您不了解数据存储、EMF 或任何东西。所以不,如果你想要便携,你就不能做延迟加载(除了你自己在你的对象中体现该信息)......即这超出了JPA规范。
DataNucleus JPA可以很好地执行事务之外的字段延迟加载。显然,您需要说明您是使用 TRANSACTION 还是 EXTENDED持久性上下文运行,因为在前一种情况下,对象在事务提交时被分离(一旦分离就不能延迟加载),而在后者中,对象仍然存在MANAGED(在这种情况下您可以延迟加载)。