Spring Data JPA中@ManyToMany的FetchType.LAZY不起作用。

8

我有三个实体:大学、学生和科目。大学和学生之间是多对多的关系,学生和科目之间也是多对多的关系。它们的实现如下。 大学:

 @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(); 

然而,这个操作返回了学生名单和相关科目,看起来当我调用u.getStudents()时,它不仅获取了学生,还获取了科目,尽管FetchType是LAZY。请提供建议。

编辑: UniversityRepo

public interface UniversityRepo extends JpaRepository<University, BigInteger> {

    public University findByUnivId(String id);
}

在调用 u.getStudents() 时,我可以看到已经加载了主题。在调试模式下,我可以看到有一个选择器 University u=UniversityRepo.findByUnivId("1234") 和接下来的两个连续选择查询,即 _u.getStudents()_。谢谢! - Babun
1
当然,在调试模式下您会看到它们,因为这会触发加载...一旦检查了集合,它就会被检索。 - M. Deinum
正如 @M.Deinum 所强调的那样,请尝试执行 u.getStudents().get(0).getName() - AlexGreg
1
如果您查看学生,调试器会检查字段以获取它们的显示,这反过来会触发加载。 - M. Deinum
3
不,因为这就是应该的:只有在被访问时才加载它。为了验证调试器是否正在惰性加载它,您可以启用查询输出,设置断点在“getStudents()”之后。现在,您不应该看到任何关于主题的查询。一旦您开始检查(在调试模式下)主题集合,您应该看到查询被触发。如果是这样,惰性加载就是正常工作的。如果主题是“立即”加载的,则可能在某处有一段代码,该代码在加载学生后访问主题。 - dognose
显示剩余5条评论
1个回答

0
您可能正在使用Springboot的默认LocalEntityManagerFactory,该工厂Bean与Spring Data一起打包在spring-orm包中。这个FactoryBean的配置能力有限,建议仅用于纯粹使用JPA进行数据访问的独立应用程序。如果您想为外部数据源设置持久性提供程序和/或全局事务(跨多个资源),或将其部署到完整的Java EE应用服务器并通过JNDI访问已部署的EntityManagerFactory,请考虑使用LocalContainerEntityManagerFactoryBean。
这里我留下了两个重要的链接以获得更好的文档:Spring JPALocalContainerEntityManagerFactoryBean

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接