NestJS中Mongoose pre-save钩子失效问题排查与解决求助
Mongoose pre-save钩子不生效问题排查与解决(NestJS环境)
问题根源分析
- 钩子绑定时机错误:你是在
mongoose.model()创建模型之后,才给Schema添加pre-save钩子。Mongoose生成模型时会固化Schema的所有配置,后续添加的钩子不会被模型应用。 - Model名称大小写不匹配:Schema中定义的模型名是
GenieJourney,但Module里MongooseModule.forFeatureAsync配置的name是Geniejourney(小写j),导致Nest无法正确关联模型与Schema。 - 业务实现方式可优化:pre-save钩子仅在
save()方法触发时生效,无法覆盖update()等批量操作,用数据库层面的复合唯一索引实现「特定公司内topic唯一」更可靠。
解决方案
步骤1:修正钩子绑定时机
将pre-save钩子移到创建模型之前,确保Schema绑定钩子后再生成模型:
// schema.ts export const GenieJourneySchemaProvider = { provide: 'GenieJourney', useFactory: (): mongoose.Model => { // 先给Schema绑定pre-save钩子 GenieJourneySchema.pre('save', async function(next) { const targetCompanyId = '66cc605febff3c565065d17b'; if (this.companyId.toString() === targetCompanyId) { // 用this.constructor代替直接引用model,避免作用域问题 const existingTopic = await this.constructor.findOne({ companyId: targetCompanyId, topic: this.topic, __deletedAt__: null }); if (existingTopic) { return next(new Error('Topic must be unique within the company.')); } } next(); }); // 再基于绑定好钩子的Schema创建模型 return mongoose.model('GenieJourney', GenieJourneySchema); } }
步骤2:统一Model名称大小写
修改module.ts中MongooseModule.forFeatureAsync的name,与Schema定义的模型名保持一致:
// module.ts @Module({ imports: [ HttpModule, MongooseModule.forFeatureAsync([ { name: 'GenieJourney', // 修正为和Schema一致的名称 useFactory: GenieJourneySchemaProvider.useFactory } ]) ], providers: [GenieJourneyService, GenieJourneySchemaProvider], controllers: [GenieJourneyController], exports: [MongooseModule], }) export class GenieJourneyModule {}
步骤3:推荐用数据库索引实现业务需求(更可靠)
如果要实现所有公司内topic+companyId+__deletedAt__的唯一性,直接添加复合唯一索引,数据库层面的约束不会漏掉任何操作(包括批量更新):
// schema.ts const GenieJourneySchema = new Schema( // 原有字段定义... ) .index({ companyId: 1, name: 1, __deletedAt__: 1 }, { unique: true }) // 新增:仅对未软删除的文档,校验companyId+topic的唯一性 .index({ companyId: 1, topic: 1, __deletedAt__: 1 }, { unique: true, partialFilterExpression: { __deletedAt__: null } }) .plugin(beautifyUnique, { message: '{PATH} 已存在 ({VALUE})', });
内容的提问来源于stack exchange,提问作者Ravi kant
相关产品推荐
相关产品推荐

