【问题标题】:OverwriteModelError while using Mongoose discriminators in NestJS在 NestJS 中使用 Mongoose 鉴别器时出现 OverwriteModelError
【发布时间】:2021-04-15 22:34:07
【问题描述】:

我关注NestJS documentation 了解如何实现 Mongoose 鉴别器,但令我惊讶的是,我不断收到OverwriteModelError。我花了几个小时找出不同示例项目的问题,但这些努力都没有成果!

我的项目树就像添加一个具有 3 个模式的事件模块一样简单:

- src
   |- event
   |    |- click-link-event.schema.ts
   |    |- event.module.ts
   |    |- event.schema.ts
   |    |- sign-up-event.schema.ts
   |- app.module.ts
   |- main.ts

这是每个文件中的代码:

// main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
// app.module.ts

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { EventModule } from './event/event.module';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost:27017/test_db'),
    EventModule,
  ],
})
export class AppModule {}
// event.module.ts

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { Event, EventSchema } from './event.schema';
import {
  ClickedLinkEvent,
  ClickedLinkEventSchema,
} from './click-link-event.schema';
import { SignUpEvent, SignUpEventSchema } from './sign-up-event.schema';

@Module({
  imports: [
    MongooseModule.forFeature([
      {
        name: Event.name,
        schema: EventSchema,
        discriminators: [
          { name: ClickedLinkEvent.name, schema: ClickedLinkEventSchema },
          { name: SignUpEvent.name, schema: SignUpEventSchema },
        ],
      },
    ]),
  ],
})
export class EventModule {}
// event.schema.ts

import { Schema, SchemaFactory, Prop } from '@nestjs/mongoose';
import { ClickedLinkEvent } from './click-link-event.schema';
import { SignUpEvent } from './sign-up-event.schema';

@Schema({ discriminatorKey: 'kind' })
export class Event {
  @Prop({
    type: String,
    required: true,
    enum: [ClickedLinkEvent.name, SignUpEvent.name],
  })
  kind: string;

  @Prop({ type: Date, required: true })
  time: Date;
}

export const EventSchema = SchemaFactory.createForClass(Event);
// click-link-event.schema.ts

import { Schema, SchemaFactory, Prop } from '@nestjs/mongoose';

@Schema()
export class ClickedLinkEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  url: string;
}

export const ClickedLinkEventSchema = SchemaFactory.createForClass(
  ClickedLinkEvent,
);
// sign-up-event.schema.ts

import { Schema, SchemaFactory, Prop } from '@nestjs/mongoose';

@Schema()
export class SignUpEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  user: string;
}

export const SignUpEventSchema = SchemaFactory.createForClass(SignUpEvent);

如您所见,我所做的只是复制文档中使用的代码。这是我在执行npm run start:dev 时遇到的错误:

[Nest] 4046   - 01/11/2021, 1:37:16 AM   [NestFactory] Starting Nest application...
[Nest] 4046   - 01/11/2021, 1:37:16 AM   [InstanceLoader] AppModule dependencies initialized
[Nest] 4046   - 01/11/2021, 1:37:16 AM   [InstanceLoader] MongooseModule dependencies initialized +0ms 
[Nest] 4046   - 01/11/2021, 1:37:16 AM   [InstanceLoader] EventModule dependencies initialized +1ms 
[Nest] 4046   - 01/11/2021, 1:37:16 AM   [InstanceLoader] MongooseCoreModule dependencies initialized +19ms 
[Nest] 4046   - 01/11/2021, 1:37:16 AM   [ExceptionHandler] Cannot overwrite `ClickedLinkEvent` model once compiled. +19ms 
OverwriteModelError: Cannot overwrite `ClickedLinkEvent` model once compiled. 
at Function.Model.discriminator (/home/saeed/sources/playground/discriminators/event-test/node_modules/mongoose/lib/model.js:1137:11 ) 
at /home/saeed/sources/playground/discriminators/event-test/node_modules/@nestjs/mongoose/dist/mongoose.providers.js:15:56 at Array.forEach (<anonymous>) 
at addDiscriminators (/home/saeed/sources/playground/discriminators/event-test/node_modules/@nestjs/mongoose/dist/mongoose.providers .js:15:20) 
at InstanceWrapper.useFactory [as metatype] (/home/saeed/sources/playground/discriminators/event-test/node_modules/@nestjs/mongoose/ dist/mongoose.providers.js:25:17) 
at Injector.instantiateClass (/home/saeed/sources/playground/discriminators/event-test/node_modules/@nestjs/core/injector/injector.j s:289:55) 
at callback (/home/saeed/sources/playground/discriminators/event-test/node_modules/@nestjs/core/injector/injector.js:42:41) 
at processTicksAndRejections (internal/process/task_queues.js:93:5) 
at async Injector.resolveConstructorParams (/home/saeed/sources/playground/discriminators/event-test/node_modules/@nestjs/core/injec tor/injector.js:114:24) 
at async Injector.loadInstance (/home/saeed/sources/playground/discriminators/event-test/node_modules/@nestjs/core/injector/injector .js:46:9) 
at async Injector.loadProvider (/home/saeed/sources/playground/discriminators/event-test/node_modules/@nestjs/core/injector/injector .js:68:9) 
at async Promise.all (index 5) at async InstanceLoader.createInstancesOfProviders (/home/saeed/sources/playground/discriminators/event-test/node_modules/@nestjs/co re/injector/instance-loader.js:43:9) 
at async /home/saeed/sources/playground/discriminators/event-test/node_modules/@nestjs/core/injector/instance-loader.js:28:13 at async Promise.all (index 5) 
at async InstanceLoader.createInstances (/home/saeed/sources/playground/discriminators/event-test/node_modules/@nestjs/core/injector /instance-loader.js:27:9)

这是 NestJS 处理它的方式中的一个错误,还是我错过了一些如此愚蠢的东西?

【问题讨论】:

  • 看看这个线程github.com/Automattic/mongoose/issues/7422。也许为 ClickedLinkEvent.name 和 SignUpEvent.name 明确设置一个字符串会有所帮助。当我尝试访问我的架构的名称属性时,我遇到了智能感知错误
  • @Baboo_ 感谢您的反馈。我尝试使用字符串文字,但可以理解的是,它不起作用,因为 ClickedLinkEvent.name 指的是 "ClickedLinkEvent" 字符串文字(我放了一个日志来仔细检查它们的值)。

标签: mongoose nestjs mongoose-schema discriminator


【解决方案1】:

我通过用 Mongoose.forFeatureAsync 替换 Mongoose.forFeature 解决了这个问题,希望这会有所帮助:

MongooseModule.forFeatureAsync([
  {
    name: Event.name,
    useFactory: () => {
      return EventSchema;
    },
    discriminators: [
      { name: ClickedLinkEvent.name, schema: ClickedLinkEventSchema },
      { name: SignUpEvent.name, schema: SignUpEventSchema },
    ],
  },
]),

【讨论】:

  • 感谢您的回答。我实际上在一开始就尝试过,似乎一切都很好,直到您尝试使用 @InjectModel() 将模型注入您的存储库中,并且会再次出现相同的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-12
相关资源
最近更新 更多