嵌套的FETCH JOIN如何使用JpaRepository和@Query注释在Hibernate上工作?

时间:2017-12-05 10:46:19

标签: java hibernate jpa java-ee

我有以下问题(伪java代码):

让我有一个A,B,C类,有以下关系:

@Entity
@Table(name = "A")
public class A {

  @OneToMany(mappedBy = "a")
  private B b; 

}


@Entity
@Table(name = "B")
public class B {

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "a_id")
  private A a;

  @OneToOne(mappedBy = "b", fetch = FetchType.LAZY)
  private C c;

}


@Entity
@Table(name = "C")
public class C {

  @OneToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "b_id")
  private B b;

}

我使用带有@Query注释的JpaRepository并实现了以下查询:

@Query("SELECT DISTINCT(a) FROM A a "
        + "LEFT JOIN FETCH a.b as b"
        + "WHERE a.id = :id ")
A findById(@Param("id") Integer id);

我想检索有关A类和B类的信息,但不是C. 不知怎的(我不知道为什么)查询试图检索B和C之间的关系。 然后,使用hibernate,启动惰性调用以检索C。

当然,如果我同时获取B和C之间的关系(添加LEFT JOIN FETCH b.c as c),那就不会发生。

我的问题是,为什么?为什么我被迫获取所有嵌套关系,而不仅仅是我需要的那些?

谢谢你。 甜瓜

2 个答案:

答案 0 :(得分:2)

Nullable @OneToOne关系总是急切地获取,如本文所述 Making a OneToOne-relation lazy

  

无约束(可空)的一对一关联是唯一的关联   没有字节码检测就无法代理。的原因   这是所有者实体必须知道是否属性   应该包含一个代理对象或NULL,它不能确定   由于一对一的正常情况,查看其基表的列   通过共享PK进行映射,因此无论如何都必须急切地获取它   代理没有意义。

答案 1 :(得分:0)

在黑暗中拍摄,但延迟加载@OneToOne - 关系存在一些问题。至少在Hibernate的旧版本中。我认为(但似乎无法找到任何文档)这是在一个较新的版本中修复的,所以如果你没有使用新版本的Hibernate,请尝试升级。