当前位置: 首页 > 面试题库 >

远程处理案例中的延迟/渴望加载策略(JPA)

徐德海
2023-03-14
问题内容

我遇到了像大多数尝试使用ORM进行远程处理的人一样的LazyLoading异常。在大多数情况下,切换到渴望获取可解决此问题(延迟加载/非原子查询/线程安全/
n + 1问题…)。但是,如果要处理非常大的对象图,那么急于获取也有缺点。

在大多数用例中,不需要加载整个对象图。加载所需的更多数据(或从db加载它们并提取所需的子集)感觉很糟糕。

那么(在运行时)有什么替代方法可以解决此类问题?
我见过:

  • 数据访问依赖项注入到域对象中,然后让该对象决定延迟加载还是渴望加载: 感觉不好 !域层应独立于任何服务。域注入也是一项昂贵的操作。该域应忽略数据访问,并且应在有或没有数据访问的情况下使用。
  • 除了需要更多数据的用例之外,其他所有内容都应懒惰地获取:似乎更好地提高了性能,但是这种方式迫使许多客户端=>服务器/数据库往返。惰性字段的初始化也会遭受痛苦(尝试使用JPA)。这种方式 不通用 ,并且受到上述相同的惰性限制的约束。
  • 将持久性封装在惰性类中:更复杂,没有与ORM互操作的最佳实践。膨胀的服务层(太多的“手写”代码 让人感到难受 )。
  • 针对每个用例使用完整的预测:我们最终将使用SQL,并放弃ORM的好处。
  • DTO /虚拟代理层提高了复杂性,并使代码难以维护(Wormhole反模式>> Bloat)。

我考虑了另一种方式。也许通用投影白名单/黑名单是一种解决方案。

想法(黑名单):定义一个类名列表,其中包含用于获取操作的边界。如果某个属性匹配并且是惰性的,请删除惰性(CGLIB)代理,然后将值填充为null。否则,简单的阻止获取(并将值保留为null)。因此,我们可以在DAO中设置明确的界限。

示例:ProductDao.findByName("Soap",Boundaries.BLACKLIST,"Category, Discount")
最后两个参数也可以绑定到Boundaries对象中。

想法(白名单):与黑名单类似,但是您必须声明的属性应加载到白名单中。

您如何看待这种解决方案?(可能的问题,限制,优点…)我应该如何用Java编写它?也许通过AOP来匹配DAO方法(因为我可以在那里修改cglib代理行为)?


问题答案:
  1. 您可以摆脱所有集合,而使用它NamedQueries。我们在一个项目(EJB + Swing)中使用了这种方法,并且效果很好-因此,您可以确定要提取的确切数据。NamedQueries是常规查询,请将其想象为PreparedStatement-s。这个想法不是用查询创建/删除/更新/删除单个对象。这个想法是您通过查询获取 Collections 。例如,而不是映射@ManyToMany列表,而是定义一个获取该列表的NamedQuery。因此,您可以单独获取收集数据,并且仅在需要时才获取,而不是自动获取。

  2. 对传输的对象使用自定义代理(使用CGLIB)-每当引用一个集合(通过其getter)时,尝试进行回溯并捕获其中任何LazyInitializationException一个,并为所请求的数据调用服务器层。

  3. 与上一个一样,但是仅对集合进行代理,就像Hibernate在需要延迟初始化时对其进行代理一样。

  4. 另外,请查看“ 值列表处理程序”模式-可能有用。

hibernate.max_fetch_depth如果适合您的情况,也可以结合使用(如果使用Hibernate)上述各项。)



 类似资料:
  • 本文向大家介绍Hibernate中的延迟加载和渴望加载之间的区别,包括了Hibernate中的延迟加载和渴望加载之间的区别的使用技巧和注意事项,需要的朋友参考一下 Lazy和Eager是ORM中的两种数据加载策略,例如休眠和Eclipse链接。当一个实体类引用其他实体(例如Employee和Phone(员工中的电话))时,我们使用了这些数据加载策略。  延迟加载-仅当我们显式调用getter或si

  • 问题内容: 我有一个Hibernate对象,其属性都被延迟加载。这些属性大多数是其他Hibernate对象或PersistentSets。 现在,我想强制Hibernate只渴望一次加载这些属性。 当然,我可以通过“接触”这些属性中的每一个,但是也许还有另一种方法可以实现我的目标。 问题答案: 该文档将其如下所示: 您可以在HQL中强制执行通常急切的属性获取。 参考文献 Hibernate Cor

  • 问题内容: 我相信只有两种使用Hibernate加载对象的方法,即延迟加载和一种渴望加载。延迟加载有其自身的优势,它不会加载很多对象,而只是在需要时才加载它们。我还了解到,如果您想强制为一个对象加载所有子代,则只需调用即可。假设我们有以下对象 假设我们有一些客户在我们的系统中有订单,并且该订单可能不止一个甚至为空。所以我的问题是,在这种情况下始终使用渴望加载会更好吗?我们需要与客户相关的订单的大小

  • 描述 (Description) 延迟加载可应用于图像,背景图像和淡入效果,如下所述 - 对于图像 要在图像上使用延迟加载,请按照给定的步骤进行操作 - 使用data-src属性而不是src属性来指定图像源。 将类lazy添加到图像。 <div class = "page-content"> ... <img data-src = "image_path.jpg" class = "l

  • 问题内容: hibernate的新手。 我有用户组多对多关系。三个表:User,Group和UserGroup映射表。 实体: 注意,在组实体中,我正在使用获取方法EAGER。现在,当我打电话给DAO时,请使用以下条件来检索系统中的所有组: 我从mappgin表(用户组)获取所有行,而不是获取组的实际数量… 例如,如果我在用户表中 在组表中 在用户组表中 结果将是以下列表-{grp1,grp2,g

  • 问题内容: 我在JPA实体中的延迟加载属性有问题。我读过许多类似的问题,但它们与spring或hibernate有关,并且他们的后代不适用或没有帮助。 该应用程序是在Wildfly应用程序服务器上运行的JEE和JPA2.1。有两个实体,DAO会话bean和servlet将它们放在一起: 当我运行此代码时,它失败并显示: 我对WebLogic / JPA1使用了非常相似的模式,并且运行平稳。任何的想