【问题标题】:Hibernate very slow with Multiple @OneToOne relationships多个@OneToOne 关系的休眠非常慢
【发布时间】:2024-04-26 03:45:02
【问题描述】:

我遇到了休眠问题。问题是某些查询需要很长时间才能执行。 我发现其中一个实体“客户”与另一个实体“地址”有 3 个关系@OneToOne - 用于不同类型的地址:“managementAddress”、“correspondenceAddress”和“buildingAddress”。在“地址”实体中,与“客户”实体没有关系。我发现缓慢的加载来自这些关系。 @OneToOne 关系被急切地初始化。我不允许更改模型关系。有谁知道我怎样才能提高执行速度?谢谢。

这是在“客户”实体中声明关系的方式:

@OneToOne(optional=true)
@Cascade(org.hibernate.annotations.CascadeType.ALL)
private Address managementAddress;

这是来自 Hibernate 统计数据的示例,用于加载 50 个“客户端”实体:

7248515 nanoseconds spent acquiring 51 JDBC connections;
2583681 nanoseconds spent releasing 51 JDBC connections;
43894536 nanoseconds spent preparing 203 JDBC statements;
4106621728 nanoseconds spent executing 203 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;

【问题讨论】:

  • 如果是多个查询,请在persistence.xml中启用show_sql,并在主时间手动在数据库中执行,检查数据库日志和配置文件,如果可能的话
  • 感谢您的建议。我试过了,似乎 Hibernate 生成了多个 Select 语句来检索每个客户端的 3 个地址。我猜应该有一些方法可以优化这个获取过程。

标签: java database hibernate jpa jakarta-ee


【解决方案1】:

仅在需要时将FetchType.LAZY 标记为延迟加载地址。

@OneToOne(optional=true, fetch=FetchType.LAZY)
@Cascade(org.hibernate.annotations.CascadeType.ALL)
private Address managementAddress;

【讨论】:

  • 感谢您的建议。地址经常被使用,所以即使我将它们标记为惰性,我也必须将它们加载到多个页面上。想知道是否有办法优化这种关系获取?
  • 如果你在你的 ORM 中正确配置缓存将不会被多次加载。
  • 谢谢,缓存帮了大忙。