我有两节课InvitedPerson
and Flight
彼此之间具有一对一的关系。以下是它们的注释方式。
public class InvitedTech{
...
@OneToOne(mappedBy="invitedTech", cascade = CascadeType.ALL, fetch=FetchType.LAZY)
public Flight flight;
@OneToOne(mappedBy="invitedTech", cascade = CascadeType.ALL, fetch=FetchType.LAZY)
public Hotel hotel;
...
}
public class Flight{
...
@OneToOne
@JoinColumn(name="invitedTechId", nullable=false)
public InvitedTech invitedTech;
...
}
如你看到的Flight
是该关系的所有者,并且InvitedTech
是这种双向关系的另一面。 InvitedTech 还拥有一个OneToOne
有关系Hotel
现在,当我编写一个简单的查询来获取所有航班时,它总共触发了三个查询。第一个得到了结果,但引发了 2 个额外的查询。
List<Flight> flg = JPA.em().createQuery("SELECT flg from Flight flg").getResultList();
- 获取所有航班的查询(这是我唯一需要的)
- 通过 InvitedTech 和 Flight 之间的联接进行查询
- 通过 InvitedTech 和 Hotel 之间的联接进行查询
即使我设置了 FetchType=Lazy,为什么仍执行查询 2&3。我没有访问酒店信息。并且 Flight 不应再次查询,因为第一个查询返回数据。
经过一番尝试后,当我删除时mappedBy
来自两个注释的属性,这两个附加查询不会被执行(即只有第一个被执行)。
为什么mappedBy
属性会导致执行额外的查询,即使FetchType=Lazy
。有办法阻止这种情况吗?
我相信这是由于 Hibernate 的特性之一造成的:
无论非可选的一对一关系是否映射为惰性关系,都会立即加载。
这背后的原因是,由于引擎无论如何都必须查看关联表 - 以确定是否应该将关联设置为代理或空 - 那么它也可能会加载关联的实体。
我自己也经历过这种情况,据我所知,唯一的解决方法是用 option=false 标记关系,这告诉 Hibernate 它始终可以设置代理。
如果关系是可选的,那么唯一的其他选项似乎是字节码检测。
也可以看看:
https://community.jboss.org/wiki/SomeExplanationsOnLazyLoadingone-to-one
使 OneToOne 关系变得懒惰
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)