在我们正在开发的这个应用程序中,我们注意到视图特别慢。我分析了视图并注意到 hibernate 执行了一个查询,即使数据库中只有两个对象需要获取,该查询也花费了 10 秒。全部OneToMany
and ManyToMany
关系很懒惰,所以这不是问题。当检查实际执行的 SQL 时,我注意到查询中有超过 80 个连接。
进一步检查该问题,我注意到问题是由深层层次结构引起的OneToOne
and ManyToOne
实体类之间的关系。所以,我想,我会让他们变得懒惰,这应该可以解决问题。但注释要么@OneToOne(fetch=FetchType.LAZY)
or @ManyToOne(fetch=FetchType.LAZY)
似乎不起作用。要么我得到一个异常,要么它们实际上没有被代理对象替换,因此很懒。
有什么想法让我让它发挥作用吗?请注意,我不使用persistence.xml
定义关系或配置细节,一切都是在java代码中完成的。
首先,一些澄清KLE的回答:
-
无约束(可为空)一对一关联是唯一一种在没有字节码检测的情况下无法代理的关联。这样做的原因是所有者实体必须知道关联属性是否应该包含代理对象或 NULL,并且它无法通过查看其基表的列来确定,因为一对一通常是通过共享 PK 映射的,所以它无论如何都必须急切地获取代理,这使得代理毫无意义。这是一个更详细解释。
-
多对一关联(显然是一对多)不会遇到这个问题。所有者实体可以轻松检查自己的 FK(在一对多的情况下,最初会创建空集合代理并根据需要填充),因此关联可以是惰性的。
-
用一对多代替一对一几乎从来都不是一个好主意。您可以将其替换为独特的多对一,但还有其他(可能更好)的选项。
Rob H.有一个有效的点,但是根据您的模型,您可能无法实现它(例如,如果您的一对一关联is可为空)。
现在,就原来的问题而言:
A) @ManyToOne(fetch=FetchType.LAZY)
应该可以正常工作。您确定它没有在查询本身中被覆盖吗?可以指定join fetch
在 HQL 中和/或通过 Criteria API 显式设置获取模式,该模式优先于类注释。如果情况并非如此,并且您仍然遇到问题,请发布您的类、查询和结果 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!!!由于渴望一对一关联而加入,你会遇到比这更大的问题:-)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)