JPA中的其他查询

我有两个类InvitedPersonFlight ,彼此之间有一对一的关系。 以下是它们的注释方式。

 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(); 
  1. 获取所有航class的查询(这是我唯一需要的航class)
  2. 通过InvitedTech和Flight之间的连接进行查询
  3. 通过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。