gpt4 book ai didi

java - 如何使 JPA OneToOne 关系变得懒惰

转载 作者:IT老高 更新时间:2023-10-28 12:17:13 26 4
gpt4 key购买 nike

在我们正在开发的这个应用程序中,我们注意到 View 特别慢。我对 View 进行了分析,并注意到 hibernate 执行了一个查询,即使数据库中只有两个对象要获取,它也需要 10 秒。所有 OneToManyManyToMany 关系都是惰性的,所以这不是问题。在检查正在执行的实际 SQL 时,我注意到查询中有超过 80 个连接。

进一步检查问题,我注意到问题是由实体类之间的 OneToOneManyToOne 关系的深层层次结构引起的。所以,我想,我会让他们偷懒,这应该可以解决问题。但是注释 @OneToOne(fetch=FetchType.LAZY)@ManyToOne(fetch=FetchType.LAZY) 似乎不起作用。要么我得到一个异常,要么它们实际上没有被代理对象替换,因此很懒。

任何想法我将如何让它工作?请注意,我不使用 persistence.xml 来定义关系或配置细节,一切都在 java 代码中完成。

最佳答案

首先,对 KLE 的回答进行一些澄清:

  1. 无约束(可为空)一对一关联是唯一一个在没有字节码检测的情况下无法代理的关联。这样做的原因是所有者实体必须知道关联属性是否应该包含代理对象或 NULL,并且由于通常通过共享 PK 进行一对一映射,因此它无法通过查看其基表的列来确定这一点,因此它无论如何都必须急切地获取代理,这使代理毫无意义。这是 more detailed解释。

  2. 多对一关联(显然还有一对多)不受此问题的影响。 Owner 实体可以轻松检查自己的 FK(如果是一对多,则最初创建空集合代理并按需填充),因此关联可以是惰性的。

  3. 用一对多代替一对一几乎不是一个好主意。您可以将其替换为独特的多对一,但还有其他(可能更好)选项。

Rob H.有一个有效的点,但是根据您的模型,您可能无法实现它(例如,如果您的一对一关联 可以为空)。

现在,就原始问题而言:

A) @ManyToOne(fetch=FetchType.LAZY) 应该可以正常工作。您确定它没有在查询本身中被覆盖吗?可以在 HQL 中指定 join fetch 和/或通过优先于类注释的 Criteria API 显式设置获取模式。如果情况并非如此,并且您仍然遇到问题,请发布您的类(class)、查询和生成的 SQL,以便进行更多中肯的对话。

B) @OneToOne 比较棘手。如果它绝对不能为空,请按照 Rob H. 的建议进行指定:

@OneToOne(optional = false, fetch = FetchType.LAZY)

否则,如果您可以更改数据库(将外键列添加到所有者表),请执行此操作并将其映射为“已加入”:

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="other_entity_fk")
public OtherEntity getOther()

在其他实体中:

@OneToOne(mappedBy = "other")
public OwnerEntity getOwner()

如果您无法做到这一点(并且无法忍受急切的获取),那么字节码检测是您唯一的选择。我必须同意 CPerkins,但是 - 如果你有 80!!! 由于渴望 OneToOne 关联而加入,那么你会遇到更大的问题 :-)

关于java - 如何使 JPA OneToOne 关系变得懒惰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1444227/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com