调试器断点不会影响Hibernate生成的sql查询

调试器断点不会影响Hibernate生成的sql查询,hibernate,spring-boot,debugging,jpa,spring-data-jpa,Hibernate,Spring Boot,Debugging,Jpa,Spring Data Jpa,我尝试将子实体C(细节)从实体A(项目)移动到实体B(项目) 我将子实体C(细节)放入临时变量 为实体A设置空实体C(详细信息) 使用JpaRepository保存实体A 将临时变量数据设置为实体B 使用JpaRepository保存实体B 只有当我在步骤3:使用JpaRepository保存实体A上设置断点时,此操作才能正常工作。我可以在最终日志中看到删除然后插入查询: Hibernate: delete from project_details where project_id=? ...

我尝试将子实体C(细节)从实体A(项目)移动到实体B(项目)

  • 我将子实体C(细节)放入临时变量
  • 为实体A设置空实体C(详细信息)
  • 使用JpaRepository保存实体A
  • 将临时变量数据设置为实体B
  • 使用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();
    
        }
    
    @Transactional
    public void moveProject(最终原子参考项目接收者,最终项目已移动){
    projectRecipientDB=projectRepository.findOne(projectRecipient.get().getId());
    projectMovedDB=projectRepository.findOne(projectMoved.getId());
    设置projectDetailsCurrent=projectMovedDB.getDetails();
    setDetails(新的HashSet());
    projectRepository.save(projectMovedDB);//断点
    projectRepository.flush();
    projectRecipientDB.setDetails(合并集(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<>());
    
    
    Set projectDetailsCurrent=projectMovedDB.getDetails();
    Logger.getLogger(ProjectService.class.getName()).error(“projectDetailsCurrent2 size=“+projectDetailsCurrent.size());
    setDetails(新的HashSet());
    

    也许有人有解释,谢谢

    我不知道为什么您在调试/不调试时会有不同的行为,但是:

    • 你有没有试过最后只冲一次水
    • 另一个选项应该是在第一个.flush()之后调用projectRepository.clear()

    它使用断点,因为子实体(细节)连接到主实体项目,如下所示:

    @OneToMany(fetch = FetchType.LAZY) 
    private Set<ProjectDetail> details = new HashSet<>(0);
    
    @OneToMany(fetch=FetchType.LAZY)
    私有集详细信息=新哈希集(0);
    
    调试器调用此元素并从DB中惰性地获取它,如果没有调试器,您可以只获取大小(仅用于填充此变量):

    Set projectDetailsCurrent=projectMovedDB.getDetails();
    projectDetailsCurrent.size();
    
    我在试图弄清楚为什么只使用调试模式检索数据时遇到了同样的问题。我意识到我执行项目mvn spring boot:run的方式没有启用惰性模式。因此,直接作为JAR文件调用或使用默认STS IDE自动执行启用了spring boot应用程序的hibernate lazy。

    感谢Pilpo的回答,是的,我最后只尝试了一次使用flush。我的projectRepository上没有方法clear(),它是从org.springframework.data.jpa.repository.jparepository扩展而来的。哦,我只是想了一些别的东西,而不是“Set-projectDetailsCurrent=projectMovedDB.getDetails();”,尝试创建一个像“Set-projectDetailsCurrent=new-Set(projectMovedDB.getDetails());”这样的新副本。可能里面的参考资料有问题。“projectDetailsCurrent”是对旧集的引用,但刷新后,旧集将被删除。因此,您稍后将在“mergeSet()”上引用一个空集。
    Set<ProjectDetail> projectDetailsCurrent = projectMovedDB.getDetails(); 
    projectDetailsCurrent.size();