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
相关产品推荐
相关产品推荐

