简体   繁体   中英

OverwriteModelError while using Mongoose discriminators in NestJS

I followed NestJS documentation on how to implement Mongoose discriminators but to my surprise, I constantly get OverwriteModelError . I spend hours figuring out the problem with different sample projects but none of those efforts were fruitful!

My project tree is just as simple as adding one event module with 3 schemas:

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

And here is the code in each of those files:

// 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);

As you can see, what I've done is merely copying the code that is used in the documentation. Here is the error I get when I do 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)

Is it a bug in the way NestJS handles it or am I missing something so stupid?

I solved this problem by replacing Mongoose.forFeature with Mongoose.forFeatureAsync, hope this will help:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM