调试器断点确实会影响Hibernate生成的SQL查询

时间:2019-05-03 12:46:41

标签: hibernate spring-boot debugging jpa spring-data-jpa

我尝试将子实体C(详细信息)从我的实体A(项目)移动到实体B(项目)

  1. 我将实体C(详细信息)放入临时变量
  2. 为实体A设置空的实体C(详细信息)
  3. 使用JpaRepository保存实体A
  4. 将临时变量数据设置为实体B
  5. 使用JpaRepository保存实体B

仅当我在第3步上设置断点时,此方法才能正常工作:使用JpaRepository保存实体A。我可以看到删除,然后在最终日志中插入查询:

Hibernate: delete from project_details where project_id=? 
...
Hibernate: insert into project_details (project_id, details_id) values (?, ?)

但在步骤3中没有断点,我只是在两个实体中丢失了实体C(详细信息)(仅在查询日志中删除) 我如何解决该问题才能正常工作而不会断点?

    @Transactional
    public void moveProject(final AtomicReference<Project> projectRecipient, final Project projectMoved) {
        Project projectRecipientDB = projectRepository.findOne(projectRecipient.get().getId());
        Project projectMovedDB = projectRepository.findOne(projectMoved.getId());

        Set<ProjectDetail> projectDetailsCurrent = projectMovedDB.getDetails();
        projectMovedDB.setDetails(new HashSet<>());
        projectRepository.save(projectMovedDB); //breakpoint 
        projectRepository.flush();

        projectRecipientDB.setDetails(mergeSet(projectRecipientDB.getDetails(), projectDetailsCurrent));
        projectRepository.save(projectRecipientDB);
        projectRepository.flush();

    }

UPD:我以某种方式使这段代码起作用,我只是输入了

Set<ProjectDetail> projectDetailsCurrent = projectMovedDB.getDetails(); 
Logger.getLogger(ProjectService.class.getName()).error("projectDetailsCurrent2 size = "+projectDetailsCurrent.size() ); 
projectMovedDB.setDetails(new HashSet<>());

works don't 也许有人解释了,谢谢

3 个答案:

答案 0 :(得分:0)

我没有理由说明为什么有/没有调试有不同的行为,但是:

  • 您是否尝试过只冲洗一次?
  • 另一个选项应该在第一个.flush()之后立即调用projectRepository.clear()

答案 1 :(得分:0)

它与断点一起工作,因为子实体(细节)以以下方式连接到主实体项目:

@OneToMany(fetch = FetchType.LAZY) 
private Set<ProjectDetail> details = new HashSet<>(0);

调试器调用此元素,然后LAZY从数据库中获取它,而无需调试器,您就可以得到大小(仅用于填充此变量):

Set<ProjectDetail> projectDetailsCurrent = projectMovedDB.getDetails(); 
projectDetailsCurrent.size();

答案 2 :(得分:0)

我在试图弄清楚为什么只使用调试模式检索数据时遇到了同样的问题。我意识到我执行项目 mvn spring-boot:run 的方式没有启用懒惰模式。所以直接作为 JAR 文件调用或者使用默认的 STS IDE 来执行 spring boot 应用程序启用了 hibernate lazy 自动。