JPA中的其他查询

时间:2013-11-19 15:00:09

标签: java sql hibernate jpa jpql

我有两个班级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与OneToOne的关系也Hotel现在,当我编写一个简单的查询来获取所有航班时,它总共会触发三个查询。第一个让我得到结果,但又引发了2个额外的查询。

List<Flight> flg = JPA.em().createQuery("SELECT flg from Flight flg").getResultList();
  1. 获取所有航班的查询(这是我唯一需要的航班)
  2. 使用InvitedTech和Flight
  3. 之间的联接进行查询
  4. 使用inviteTech和Hotel
  5. 之间的联接查询

    为什么即使我设置了FetchType = Lazy,也会执行查询2和3。我没有访问酒店信息。并且当第一个查询返回数据时,Flight不应再次成为查询。

    当我从两个注释中删除mappedBy属性时,一些玩游戏后,这两个附加查询不会被执行(即只执行第一次)。

    为什么mappedBy属性会导致执行其他查询,即使FetchType=Lazy也是如此。有办法阻止这个吗?

2 个答案:

答案 0 :(得分:2)

我认为这是由于Hibernate的特性之一:

无论是否将它们映射为Lazy,都会急切地加载

非可选的一对一关系。

这背后的原因是,因为引擎必须查看关联表 - 确定它是应该将关联设置为代理还是作为null - 然后它也可以加载关联的实体。

我自己也经历过这一点,据我所知,唯一的方法是使用optional = false标记关系,告诉Hibernate它总能设置代理。

如果关系是可选的,那么唯一的其他选项似乎是字节码检测。

另见:

https://community.jboss.org/wiki/SomeExplanationsOnLazyLoadingone-to-one

Making a OneToOne-relation lazy

答案 1 :(得分:0)

您尚未设置从Flight到InvitedTech lazy的关联。因此它加载与航班相关联的InvitedTech。

由于无法从InvitedTech知道是否存在与InvitedTech相关联的酒店和航班,因此无法确定这些字段是否应为空或应为代理。因此,它被迫执行其他查询以了解InvitedTech是否存在酒店/航班。