You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate FetchType.LAZY单元测试已插入数据却查询返回0条记录问题

问题根因
  • 你当前操作的StockEntity实例是代码中手动new的对象,并非JPA持久化上下文托管的实体对象:懒加载(FetchType.LAZY)仅对持久化上下文托管的实体生效,手动构造的对象调用getter只会返回初始化时的空集合,不会触发数据库查询。
  • 插入子记录时仅维护了子实体指向父实体的关联,没有同步维护父实体的子集合字段:循环里只给stockDailyRecordEntity.setStock(stockEntity),但没有把新建的子实体add到stockEntity.getStockDailyRecords()集合里,所以这个手动构造的父对象的集合本身就是空的。
  • 最后调用的stockRepo.save(stockEntity)也不会自动填充子集合字段:save操作只会把传入对象的字段值同步到数据库,不会反向查询数据库的子记录回填到这个对象的集合里。
修复方案
  • 方法1:插入子记录时同步维护父对象的子集合
    调整循环内逻辑,直接往父对象的原生子集合中添加子实体即可:
    // 父对象初始化后直接持有其自带的子集合
    Set<StockDailyRecordEntity> stockDailyRecords = stockEntity.getStockDailyRecords();
    for (int i = 0; i < 1000; i++) {
        StockDailyRecordEntity stockDailyRecordEntity = new StockDailyRecordEntity();
        stockDailyRecordEntity.setStock(stockEntity);
        stockDailyRecordEntity.setDesc(new Date().toString());
        // 子实体同步加入父对象的集合
        stockDailyRecords.add(stockDailyRecordEntity);
        stockDailyReportRepo.save(stockDailyRecordEntity);
    }
    
  • 方法2:需要懒加载子集合时,先从数据库重新查询父实体(推荐,符合JPA规范)
    存完所有数据后,先通过主键查询拿到持久化上下文托管的父实体,再获取子集合即可触发正常懒加载:
    log.info("Total StockDailyRecordEntity Inserted ----->" + stockDailyReportRepo.findAll().size());
    // 重新查询获得托管态父实体
    StockEntity managedStock = stockRepo.findById(stockEntity.getStockId()).get();
    log.info("Starting Lazy Search");
    Set<StockDailyRecordEntity> setLazy = managedStock.getStockDailyRecords();
    // 此时调用size会触发懒加载查询,返回正确的1000条
    log.info("Starting Lazy Search size ==>" + setLazy.size());
    

内容的提问来源于stack exchange,提问作者wikey321

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 11:09:02