在我的项目中,我有三个这样的实体:
@Entity
public class A {
@Id
private int id;
}
@Entity
public class B {
@Id
private int id;
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, optional = false)
@OnDelete(action = OnDeleteAction.CASCADE)
private A a;
}
@Entity
public class C {
@Id
private int id;
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, optional = false)
@OnDelete(action = OnDeleteAction.CASCADE)
private B b;
}
正如您所看到的,C
与A
具有明显的ManyToOne-Relationship关系。
现在,我想使用C
获取具有特定A
的所有JpaRepository
:
public interface CRepository extends JpaRepository<C, Integer> {
List<C> findAllByBA(A a);
}
这导致了以下Hibernate sql查询(很好):
休眠:选择...来自c c0_交叉连接b b1_其中c0_.b_id = b1_.id和b1_.a_id =?
但之后我得到了另一个查询,每个不同的B
(可能是几千,所以不是很好):
休眠:选择...从b b0_ inner加入一个a1_ on b0_.a_id = a1_.id其中b0_.id =?
显然,这可以通过使用所有三个表的单个连接来解决。但如何告诉Hibernate 这样做而不会失去JpaRepository
抽象的便利性?
答案 0 :(得分:1)
额外的,不需要的查询是由关联渴望的事实引起的。为了避免加载B,你应该使关联变得懒惰:
@ManyToOne(fetch: FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, optional = false)
我通常会让每个协会都懒惰。如果你对Bs不感兴趣,或者事先不知道是否需要加载Bs,那么使关联变得懒惰可以避免加载它们。如果您知道您希望将B与C一起加载,那么您只需在查询中明确加载它们:
@Query("select c from C c left join fetch c.b where c.b.a = ?")