【发布时间】:2015-12-11 16:14:43
【问题描述】:
我有 3 个实体 University、Student 和 Subject。 University 和 Student 有一个多对多的关系,而 Student 和 Subject 也有一个多对多的关系。它们的实现如下。 大学:
@ManyToMany(fetch=FetchType.LAZY)
@JoinTable(
name="UNIV_TO_STD_REL"
, joinColumns={
@JoinColumn(name="UNIV_DBKY", referencedColumnName="UNIV_DBKY")
}
, inverseJoinColumns={
@JoinColumn(name="STD_DBKY", referencedColumnName="STD_DBKY")
}
)
private List<Student> students;<br>
学生:
@ManyToMany(mappedBy="students")
private List<University> universities;
@ManyToMany(fetch=FetchType.LAZY)
@JoinTable(
name="STD_TO_SUB_REL"
, joinColumns={
@JoinColumn(name="STD_DBKY", referencedColumnName="STD_DBKY")
}
, inverseJoinColumns={
@JoinColumn(name="SUB_DBKY", referencedColumnName="SUB_DBKY")
}
)
private List<Subject> subjects;<br>
主题:
@ManyToMany(mappedBy="subjects")
private List<Student> students;
现在,我想招收特定大学的学生,但不是相关学科。所以,我调用存储库如下:
University u=UniversityRepo.findByUnivId("1234");
u.getStudents();
但是,这也向我返回了学生列表以及来自 Subject 的相关科目。似乎当我调用 u.getStudents() 时,它不仅获取学生,还获取主题,虽然 FetchType 是 LAZY。
请提出建议。
编辑: 大学回购
public interface UniversityRepo extends JpaRepository<University, BigInteger> {
public University findByUnivId(String id);
}
【问题讨论】:
-
你能展示
UniversityRepo.findByUnivId的实现吗?你如何确定主题已加载?请记住,如果您检查调试器中的值,(Student.getSubjects())它也会触发延迟加载。因此,请检查控制台上的查询(启用输出),此时主题已真正加载。 -
我可以看到在调用 u.getStudents() 时已加载科目。在调试模式下,我可以看到有一个 University u=UniversityRepo 的选择。 findByUnivId("1234") 和下一步中的 2 个连续选择查询,即 u.getStudents()。谢谢!
-
当然,您会在调试模式下看到它们,因为这会触发加载...一旦您检查集合,它将被检索。
-
如果您查看学生,您的调试器正在检查字段以显示它们,这反过来会触发加载。
-
@Babun 不,因为它应该是这样的:如果它被访问,则加载它。要验证它是由调试器延迟加载的,您可以启用查询输出,在“getStudents()”之后设置一个断点。您现在应该看不到任何关于主题的查询。一旦您开始检查(在调试模式下)主题集合,您应该会看到正在触发的查询。如果是这样,则 LazyLoading 工作正常。如果主题是“立即”加载的,您可能在某处有一段代码,在加载学生后访问主题。