在我们正在开发的此应用程序中,我们注意到一个 View 特别慢。我剖析了该 View ,发现即使数据库中只有两个对象要获取,hibernate仍然执行了一个查询,该查询花费了10秒。所有OneToMany
和ManyToMany
关系都是惰性的,因此这不是问题。在检查实际执行的SQL时,我注意到查询中有80多个联接。
在进一步检查该问题时,我注意到该问题是由实体类之间的OneToOne
和ManyToOne
关系的深层次结构引起的。因此,我想,我只是让它们变得懒惰,应该可以解决问题。但是注释@OneToOne(fetch=FetchType.LAZY)
或@ManyToOne(fetch=FetchType.LAZY)
似乎不起作用。要么我得到一个异常(exception),要么然后它们实际上没有被代理对象替换,因此变得懒惰。
任何想法,我将如何使它工作?请注意,我不使用persistence.xml
定义关系或配置详细信息,所有操作均在Java代码中完成。
最佳答案
首先,对 KLE 的答案进行一些说明:
Rob H. 有一个有效的观点,但是您可能无法实现它,具体取决于您的模型(例如,如果一对一关联是可为空的)。
现在,就原始问题而言:
A)
@ManyToOne(fetch=FetchType.LAZY)
应该可以正常工作。您确定查询本身不会覆盖它吗?可以在HQL中指定join fetch
和/或通过Criteria API显式设置获取模式,这将优先于类注释。如果不是这种情况,但您仍然遇到问题,请发布您的类(class),查询和生成的SQL,以进行更多的即时对话。B)
@OneToOne
比较棘手。如果绝对不能为空,请遵循Rob H.的建议,并这样指定:@OneToOne(optional = false, fetch = FetchType.LAZY)
否则,如果您可以更改数据库(向所有者表添加外键列),请进行更改并将其映射为“joined”:
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="other_entity_fk")
public OtherEntity getOther()
并在OtherEntity中:
@OneToOne(mappedBy = "other")
public OwnerEntity getOwner()
如果您不能做到这一点(并且不能随心所欲地抓取),则字节码检测是您唯一的选择。我必须同意 CPerkins ,但是-如果您有 80!由于渴望OneToOne协会而加入,因此遇到了更大的问题:-)