Hibernate:复杂对象的初始化

2023-12-28

我在合理的时间内从数据库完全加载非常复杂的对象并使用合理的查询数量时遇到问题。

我的对象有很多嵌入实体,每个实体都引用另一个实体,另一个实体引用另一个实体,依此类推(因此,嵌套级别为 6)

因此,我创建了示例来演示我想要的内容:https://github.com/gladorange/hibernate-lazy-loading https://github.com/gladorange/hibernate-lazy-loading

我有用户。

用户有@OneToMany最喜欢的收藏橙子、苹果、葡萄树和桃子。每个葡萄藤都有@OneToMany葡萄的集合。每个水果都是另一个只有一个字符串字段的实体。

我正在为用户创建每种类型 30 个最喜欢的水果,每个葡萄藤有 10 颗葡萄。因此,我在数据库中总共有 421 个实体 - 30*4 个水果、100*30 个葡萄和一个用户。

我想要的是:我想使用不超过 6 个 SQL 查询来加载它们。 并且每个查询不应产生大结果集(大是指该示例中包含超过 200 条记录的结果集)。

我理想的解决方案如下:

  • 6 个请求。第一个请求返回有关用户的信息,结果集的大小为 1。

  • 第二个请求返回有关该用户的 Apple 的信息,结果集的大小为 30。

  • 第三个、第四个和第五个请求返回与第二个相同的结果(结果集大小 = 30),但针对葡萄树、橙子和桃子。

  • 第六个请求返回所有葡萄树的 Grape

这在 SQL 世界中非常简单,但我无法使用 JPA (Hibernate) 实现这一点。

我尝试了以下方法:

  1. 使用 fetch join,例如from User u join fetch u.oranges ...。这太糟糕了。结果集为30*30*30*30,执行时间为10秒。请求数 = 3。我在没有葡萄的情况下尝试过,使用葡萄你将得到 x10 大小的结果集。

  2. 只需使用延迟加载即可。这是本例中的最佳结果(使用 @Fetch= SUBSELECT 用于葡萄)。但在这种情况下,我需要手动迭代每个元素集合。另外,子选择获取过于全局设置,所以我希望有一些可以在查询级别工作的东西。结果集和时间接近理想。 6 个查询和 43 毫秒。

  3. 加载实体图。与 fetch join 相同,但它也向每个葡萄发出请求以获取小道消息。然而,结果时间更好(6 秒),但仍然很糟糕。请求数 > 30。

  4. 我试图通过在单独的查询中“手动”加载实体来欺骗 JPA。喜欢:

    
    
    SELECT u FROM User where id=1;
    SELECT a FROM Apple where a.user_id=1;
      

这比延迟加载有点糟糕,因为它需要每个集合进行两个查询:第一个查询手动加载实体(我可以完全控制此查询,包括加载关联实体),第二个查询延迟加载相同的实体由 Hibernate 本身执行(这是由 Hibernate 自动执行的)

执行时间为52,查询次数=10(用户1次,葡萄1次,每个水果集合4*2)

实际上,“手动”解决方案与 SUBSELECT 获取相结合允许我使用“简单”获取连接在一个查询中加载必要的实体(例如@OneToOne实体)所以我要使用它。但我不喜欢必须执行两个查询来加载集合。

有什么建议么?


我通常使用以下方法覆盖 99% 的此类用例批量抓取 https://stackoverflow.com/a/35039402/4754790对于实体和集合。如果您在读取实体的同一事务/会话中处理获取的实体,那么您无需执行任何其他操作,只需导航到处理逻辑所需的关联,生成的查询将非常优化。如果您想以分离的形式返回获取的实体,则可以手动初始化关联:

User user = entityManager.find(User.class, userId);
Hibernate.initialize(user.getOranges());
Hibernate.initialize(user.getApples());
Hibernate.initialize(user.getGrapevines());
Hibernate.initialize(user.getPeaches());
user.getGrapevines().forEach(grapevine -> Hibernate.initialize(grapevine.getGrapes()));

请注意,最后一个命令将not实际上对每个小道消息执行一个查询,作为多个grapes集合(最多指定@BatchSize)在初始化第一个时被初始化。您只需迭代所有这些即可确保所有这些都已初始化。

这种技术类似于您的手动方法,但更有效(不会对每个集合重复查询),并且在我看来更具可读性和可维护性(您只需调用Hibernate.initialize而不是手动编写 Hibernate 自动生成的相同查询)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hibernate:复杂对象的初始化 的相关文章

  • 如何在 Eclipse 中用阿拉伯语读写

    我在 eclipse 中编写了这段代码来获取一些阿拉伯语单词 然后打印它们 public class getString public static void main String args throws Exception PrintS
  • 检查双精度值的等于和不等于条件

    我在比较两者时遇到困难double values using and 我创建了 6 个双变量并尝试进行比较If健康 状况 double a b c d e f if a b c d e f My code here in case of t
  • java.lang.Class: 在 java 程序中初始化 log4j 属性文件时出错

    我正在尝试使用 log4j 运行独立的 java 程序 但在调试时收到以下消息 控制台上没有 log4j 相关日志 log Logger 1343 java lang Class ERROR in 18b4aac2 有人可以建议这里出了什么
  • Java 创建浮雕(红/蓝图像)

    我正在编写一个 Java 游戏引擎 http victoryengine org http victoryengine org 并且我一直在尝试生成具有深度的 3D 图像 您可以使用那些红色 蓝色眼镜看到 我正在使用 Java2D 进行图形
  • 有没有好的方法来解析用户代理字符串?

    我有一个Java接收模块User Agent来自最终用户浏览器的字符串的行为需要略有不同 具体取决于浏览器类型 浏览器版本甚至操作系统 例如 FireFox 7 0 Win7 Safari 3 2 iOS9 我明白了User Agent由于
  • Google Inbox 类似 RecyclerView 项目打开动画

    目前 我正在尝试实现 Google Inbox 例如RecyclerView行为 我对电子邮件打开动画很好奇 我的问题是 该怎么做 我的意思是 他们使用了哪种方法 他们用过吗ItemAnimator dispatchChangeStarti
  • PropertySources 中各种源的优先级

    Spring引入了新的注释 PropertySources对于所有标记为的类 Configuration since 4 0 需要不同的 PropertySource作为论证 PropertySources PropertySource c
  • JavaFX - setVisible 隐藏元素但不重新排列相邻节点

    在 JavaFX 中 如果我有一个场景有 2VBox元素和每个VBox有多个Label in it 如果我设置顶部VBox to 无形的 为什么底部VBox 不向上移动顶部的场景VBox was The VBox is 无形的但我希望其他物
  • spring - 强制 @Autowired 字段的 cglib 代理

    我有混合堆栈 EJB 和 Spring 为了将 Spring 自动装配到 EJB 我使用SpringBeanAutowiringInterceptor 不确定这是否会影响我遇到的问题 在尝试通过以下方式自动装配 bean 时 Scope p
  • 场景生成器删除 fxml 文件中的导入

    我使用场景构建器 Gluon Scene Builder JavaFX Scene Builder 8 1 1 来创建应用程序的 UI 并使用 Eclipse 开发 JavaFX 现在 每次我在场景生成器中保存某些内容时 它都会从 fxml
  • Java替换特定字符

    这是我在这个网站上的第一个问题 所以我会尽量不要成为一个十足的菜鸟 我目前正在用java 创建刽子手游戏 所以我问你的问题是我们是否被赋予了 幽灵 这个词 并将 Ghost 替换为 hiddenWord ghost length for i
  • 为什么我在 Mac 上看到“java.lang.reflect.InaccessibleObjectException: Unable to make private java.nio.DirectByteBuffer(long,int)accessibl

    我已经在工作中愉快地构建代码好几天了 但突然我的一个项目 不是全部 失败并出现此错误消息 看看下面的答案吧 我是如何修复它的 起初我用谷歌搜索 看到很多有这个问题的人正在使用 Java 16 但我认为 错误 我正在使用 Java 11 因为
  • Install4j:如何在安装结束时执行命令行 java -jar filename.jar

    在 Intall4j 中 在安装结束时 我只想通过执行如下命令行来初始化某些内容 java jar filename jar 我怎样才能归档这个任务install4j Thanks 将 运行可执行文件或批处理文件 操作添加到 安装屏幕 并设
  • 覆盖 MATLAB 默认静态 javaclasspath 的最佳方法

    MATLAB 配置为在搜索用户可修改的动态路径之前搜索其静态 java 类路径 不幸的是 静态路径包含相当多非常旧的公共库 因此如果您尝试使用新版本 您可能最终会加载错误的实现并出现错误 例如 静态路径包含 google collectio
  • tomcat 过滤所有 web 应用程序

    问题 我想对所有网络应用程序进行过滤 我创建了一个过滤器来监视对 apache tomcat 服务器的请求 举例来说 它称为 MyFilter 我在 netbeans 中创建了它 它创建了 2 个独立的目录 webpages contain
  • 从 Java 日历迁移到 Joda 日期时间

    以前 当我第一次设计股票应用相关软件时 我决定使用java util Date表示股票的日期 时间信息 后来我体会到了大部分方法java util Date已弃用 因此 很快 我重构了所有代码以利用java util Calendar 然而
  • 在 AKKA 中,对主管调用 shutdown 是否会停止其监督的所有参与者?

    假设我有一位主管连接了 2 位演员 当我的应用程序关闭时 我想优雅地关闭这些参与者 调用supervisor shutdown 是否会停止所有参与者 还是我仍然需要手动停止我的参与者 gracias 阻止主管 https github co
  • 将 RSA 密钥从 BigIntegers 转换为SubjectPublicKeyInfo 形式

    WARNING 最初的问题是关于 PKCS 1 编码密钥 而问题中的实际示例需要SubjectPublicKeyInfo X 509 编码密钥 我目前正致力于在 java 中从头开始实现 RSA 算法 特别是密钥生成方面 现在我的代码可以给
  • 来自客户端的超时 Web 服务调用

    我正在使用 RestEasy 客户端调用网络服务 一项要求是 如果调用运行时间超过 5 秒 则中止 超时调用 我如何使用 RestEasy 客户端实现这一目标 我只看到服务器端超时 即如果在一定时间内未完成请求 Rest Easy 网络服务
  • 如何移动图像(动画)?

    我正在尝试在 x 轴上移动船 还没有键盘 我如何将运动 动画与boat png而不是任何其他图像 public class Mama extends Applet implements Runnable int width height i

随机推荐

  • 在程序的某些部分显式禁用 MySQL 查询缓存

    在 Django 项目中 一些 cronjob 程序主要用于管理或分析目的 例如生成网站使用统计数据 轮换用户活动日志等 我们可能不希望MySQL在这些程序中缓存查询以节省内存使用并提高查询缓存效率 是否可以在这些程序中显式关闭 MySQL
  • 为什么我的 HTML 文本框在移动设备和桌面上的显示效果不一样?

    由于某种原因 我的 HTML 文本框没有居中 当我在桌面和移动设备上查看它们时 它们的显示方式有所不同 一个被拉伸 而另一个未居中 我可以让我的 HTML 代码在中显示相同吗 两种情况 div div h1 style text align
  • onload 和 Jquery read()。它们适用于任何 DOM 吗?比如table或者div?

    我需要使用 javascript 脚本将动态内容放在 div 上 该 div 位于页面顶部 因此它会先加载 然后再加载其下方的其他内容 而且下面真的有很多东西 因此 当我将脚本放在ready 或onload上时 div将空2 3秒 同时显示
  • 使用 jQuery 删除表格行

    以下是我的代码 Script document ready function click click function table append tr td nbsp td tr remove click function table re
  • 在同一个 Docker Hub 存储库中进行链式自动构建

    由于构建时间限制 https stackoverflow com a 34588866 865719在 Docker Hub 上 我决定拆分Dockerfile将耗时的自动构建分为三个文件 每一个 子构建 都会在 Docker Hub 的时
  • 为什么 sem_open 与 fork() 一起使用而不使用共享内存?

    即使信号量不在共享内存中 该程序也可以工作 我测试过 请注意我如何在 fork 之前创建一次变量 另一方面 用创建的信号量sem init 需要在共享内存中才能工作 但这仍然是一个sem t结构 那么为什么它不需要共享内存呢 的内容是sem
  • 如何删除字符串中除点和逗号之外的所有特殊字符

    我有一个包含许多特殊字符和文本的句子 我想删除除点和逗号之外的所有特殊字符 例如 这就是 u HI Jhon how are you 我正在尝试生成以下字符串 HI Jhon how are you 我试过这个 u HI Jhon how
  • Swagger/OpenAPI 多重安全要求和副作用?

    我正在为 Swagger OpenAPI 实现一个代码生成器 但是 我在实现安全要求时遇到了问题 这些要求被定义为对象列表 列表成员是替代 或 对象成员是与 例如 a b c d 这应该导致 a b 光盘 然而 在实现这一点时 我遇到了实际
  • .Net 中是否有与 java.util.concurrent.Executor 等效的程序?

    拥有一组长期运行的离散任务 从文本文件中解析数十 数千行 合并为对象 操作和持久化 如果我在 Java 中实现这一点 我想我可能会为文件中的每一行或每 X 行 即块 的任务添加一个新任务到执行器 对于我正在使用的 Net 我不太确定 我怀疑
  • Xcode iOS 框架图标含义

    当使用 Xcode 7 3 将 iOS 框架添加到 iOS 项目时 常规 gt 链接的框架和库 Xcode 使用两个不同的图标来表示 iOS 框架 一个看起来像一个白色立方体 另一个看起来像一个工具箱 这些图标分别代表什么意思 工具箱图标代
  • 信号 fft 的幅度错误

    我正在尝试计算使用 Python 进行快速傅立叶变换 我正在使用函数 fft fft 并将其应用于简单的正弦信号 这是我的代码 import numpy as np import matplotlib pyplot as plt frame
  • 在分块矩阵中查找一个值

    我写了一个稀疏矩阵类 基于Block压缩存储 我写了几乎所有的方法 但我不知道如何写方法findValue i j 给出原始矩阵的 2 个索引 存储由四个向量组成 ba 按从上到下左右顺序存储矩阵的非零块 几乎有一个元素不为零的矩形块 an
  • 如何让 mod_rewrite 只匹配一次规则

    我有以下网址 http localhost http mygarble com foundationsofwebprogramming 86 http localhost http mygarble com foundationsofweb
  • Excel公式最小值的位置

    编辑 可能是一个简单的问题 基本上我有三个值 比如说不同单元格中的 9 4 和 7 不在表中 我想找到订单中的最小值 然后返回其相对位置 例如 9 4 7 将返回 2 因为 4 是最小值并且位于第二位 正确的Excel公式是什么 谢谢 解决
  • 使用Scala对象作为key的reduceByKey

    我正在将 Spark 与 scala 一起使用 并且我有一个充满 tuple2 的 RDD 其中包含一个复杂对象作为键和一个 double 目的是如果对象相同 则加倍 频率 为此 我将我的对象定义如下 case class SimpleCo
  • R 中的分组依据和条件

    我有一个具有相似名称 课程 课程和完成情况的数据框 name lt c John John John Sam Sam course lt c Driving Driving Driving Cycling Cycling lesson lt
  • 指定的子项已经有父项。您必须首先对孩子的父母调用removeView()

    我正在做一个关于输入你的名字的应用程序的小练习 它返回 你好 你输入的名字 但是在我按下按钮后 我收到错误 指定的子项已经有父项 您必须首先在子项的父项上调用removeView MainActivity java package com
  • Spring Boot 中未调用 ClientHttpRequestInterceptor

    我正在尝试使用 ClientHttpRequestInterceptor 将日志记录添加到我的应用程序 我的拦截器没有被调用 不知道这里出了什么问题 这是我的代码 Component Slf4j public final class Res
  • SQL 模式匹配

    我有一个与 SQL 相关的问题 我想匹配两个字段的相似性并返回相似程度的百分比 例如 如果我有一个名为 doc 的字段 其中包含以下内容 This is my first assignment in SQL 在另一个领域我有类似的东西 My
  • Hibernate:复杂对象的初始化

    我在合理的时间内从数据库完全加载非常复杂的对象并使用合理的查询数量时遇到问题 我的对象有很多嵌入实体 每个实体都引用另一个实体 另一个实体引用另一个实体 依此类推 因此 嵌套级别为 6 因此 我创建了示例来演示我想要的内容 https gi