【问题标题】:Hibernate @OneToMany returns null on first callHibernate @OneToMany 在第一次调用时返回 null
【发布时间】:2020-06-21 16:34:17
【问题描述】:

我正在尝试填充我的数据库,在此期间,我创建了员工和团队之间的关联。我正在尝试通过休眠 OneToMany 引用访问团队中的团队成员并进行延迟加载。这在我的应用中非常有用,除非我在创建实体后立即调用它。

我相当确定这是一个休眠事务或缓存问题,因为所有行都存在于数据库中,但我很难理解问题所在。我已尝试将 populateTeamsAndEmployees 函数中的所有保存都转换为 saveAndFlush,但这没有帮助。

如何让 team.getTeamMembers() 每次被调用时都能正常工作?

注意:这只发生在我通过RequestMapping 调用seedData() 函数时,但当我使用@Scheduled 注释调用seedData() 时不会发生这种情况


有问题的函数

    void seedData() {
       populateTeamsAndEmployees()
       otherBusinessLogic()
    }
    
    public void otherBusinessLogic() {
       List<Team> teams = teamRepository.findAll();
    
       teams.foreach(team -> {
            /*
            works great every time, returns all team members
            */
            List<Employee> teamMembers = employeeRepository.findEmployeeByTeamId(team.getId()); 


            /*
            this returns null when ran immediately after populateTeamsAndEmployees(), 
            but returns the same as the line above all other times
            */
            List<Employee> thisDoesntWork = team.getTeamMembers();
       });
    
    }

    public void populateTeamsAndEmployees() {
        List<EmployeeFromOtherSystem> employeesToConvert = otherSystemRepo.findAll();
        employeesToConvert.foreach(otherSysEmployee -> {
            employeeRepository.save(otherSysEmployee.toEmployee());
        });
    }

实体:

class Team {
    @OneToMany(mappedBy = "team", fetch = FetchType.LAZY)
    private List<Employee> teamMembers;
}

class Employee {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TEAM_ID")
    private Team team;
}

【问题讨论】:

  • 由于您已将FetchType 声明为 Lazy,因此在简单查询期间将不会从数据库中检索相关子项。 - 您可以将其更改为 @OneToMany(mappedBy = "team", fetch = FetchType.EAGER) - 但是,如果您的实体关系过于复杂或“获取”调用的数量很高,则可能会出现性能问题
  • 我也尝试将 FetchType 更改为 Eager,但这并不能解决问题。
  • 您是否也在Employee 一侧进行了调整? (只是检查,以防万一)
  • 是的,我都改成了FetchType.Eager。我假设这与在数据库中创建数据后立即调用它有关,因为team.getTeamMembers() 在任何其他时间都可以完美运行。
  • 如果是这种情况,您可能必须先提交然后获取它们(虽然我不确定,我承认我没有仔细查看代码)

标签: spring hibernate jpa spring-data-jpa


【解决方案1】:

所以问题是 JPA 在我创建实体后立即对其进行缓存。

我可以通过调用em.clear()来修复它

请参阅下文了解如何使用 JpaRepository 访问 EntityManager:
https://dzone.com/articles/accessing-the-entitymanager-from-spring-data-jpa

为什么要使用.clear()
EntityManager refresh

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-20
    • 2013-06-25
    • 2023-03-28
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多