JPA中的其他查询
我有两个类InvitedPerson
和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与Hotel
Now也有OneToOne
关系,当我写一个简单的查询来获取所有航class时,它总共会触发三个查询。 第一个得到我的结果,但引发了2个额外的查询。
List flg = JPA.em().createQuery("SELECT flg from Flight flg").getResultList();
- 获取所有航class的查询(这是我唯一需要的航class)
- 通过InvitedTech和Flight之间的连接进行查询
- 通过inviteTech和酒店之间的联接查询
为什么即使我已设置FetchType = Lazy,也会执行查询2和3。 我没有访问酒店信息。 并且当第一个查询返回数据时,Flight不应再次成为查询。
在我从两个注释中删除mappedBy
属性之后玩了一些游戏时,这两个附加查询没有被执行(即只有第一个被执行)。
为什么mappedBy
属性会导致执行其他查询,即使FetchType=Lazy
。 有办法阻止这个吗?
我相信这是由于Hibernate的特性之一:
无论是否将它们映射为Lazy,都会急切地加载非可选的一对一关系。
这背后的原因是,因为引擎必须在关联表中查找 – 确定它是应该将关联设置为代理还是为null – 然后它也可以加载关联实体。
我自己经历过这一点,据我所知,唯一的方法是使用optional = false标记关系,告诉Hibernate它总是可以设置代理。
如果关系是可选的,那么唯一的其他选项似乎是字节码检测。
也可以看看:
https://community.jboss.org/wiki/SomeExplanationsOnLazyLoadingone-to-one
使OneToOne关系变得懒散
您尚未设置从Flight到InvitedTech懒惰的关联。 因此它加载与航class相关联的InvitedTech。
由于无法从InvitedTech知道是否存在与InvitedTech相关联的酒店和航class,因此无法确定这些字段是否应为空或应该是代理。 因此,它被迫执行其他查询以了解InvitedTech是否存在酒店/航class。