NestJS中TypeORM缓存自动添加分页后缀问题咨询
TypeORM关联查询生成两条缓存记录的问题解析
问题场景
在NestJS项目中使用TypeORM实现数据库查询缓存,仅给userByIdWithColumns方法的findOne查询配置了缓存:
async userByIdWithColumns(id: string, ReqColumns: string[] = []) { const selectOptions = [ ...defaultColumns, ...ReqColumns, ]; const foundOneOptions: FindOneOptions<User> = { where: { id }, select: selectOptions, relations: { role: true, }, cache: { id: `user-findone-${id}`, milliseconds: 60 * 60 * 1000 } }; return this.userRepository.findOne(foundOneOptions); }
实际运行后发现query_result_cache表中生成了两条缓存记录:一条使用自定义的user-findone-${id}作为缓存ID,另一条则是该ID加上-pagination后缀。移除relations配置后,仅生成单条缓存记录。
使用依赖版本:
{ "typeorm": "^0.3.22", "@nestjs/typeorm": "^11.0.0", "@nestjs/core": "^10.0.2", "mysql2": "^3.14.0" }
原因分析
这是TypeORM 0.3.x版本处理关联查询时的内部逻辑导致的:
- 当
findOne查询包含relations关联配置时,TypeORM会拆分出主表查询和关联数据查询两个执行步骤 - 关联数据的查询逻辑复用了分页查询的缓存处理模块,即便没有显式设置分页参数,也会自动给这条关联查询的缓存ID添加
-pagination后缀 - 最终主表查询和关联查询分别生成了两条独立的缓存记录
处理建议
- 缓存失效处理:需要同时清理两条缓存记录,否则仅清理自定义ID的缓存后,关联数据的缓存依然会生效,导致数据不一致。
- 可以通过缓存ID前缀批量清理:比如清理所有以
user-findone-${id}开头的缓存记录 - 或者显式指定两条缓存ID分别清理
- 可以通过缓存ID前缀批量清理:比如清理所有以
- 规避方案:如果不想生成两条缓存,可以考虑改用
queryBuilder手动编写关联查询语句,替代findOne的relations配置,这样能更精准控制缓存的生成逻辑
内容的提问来源于stack exchange,提问作者Jayesh Vyavahare
相关产品推荐
相关产品推荐

