nestjs / mongoose

Mongoose module for Nest framework (node.js) 🍸
https://nestjs.com
MIT License
530 stars 118 forks source link

Mongoose hook calling twice #2235

Closed DIDIERRobin closed 1 month ago

DIDIERRobin commented 3 months ago

Is there an existing issue for this?

Current behavior

Uppon creating a new Test Object, the save hook is called twice depending on what we do inside the hook function. Importing another Document as a string, or as a class impact the behavior of the hook.

Minimum reproduction code

https://github.com/DIDIERRobin/mongoose-hook-bug

Steps to reproduce

it needs a mongodb instance running

  1. replace .env.example with .env and put your mongodb connection string
  2. run npm install
  3. run npm run start:dev

launch the creation of a "test" document:

curl -X POST http://localhost:3000/test

You will see the hook is called two times instead of one. And the second time, the instance is ont a document anymore, therefore this.model does not exist. To correct the issue, follow the instruction in the comment inside test/hook.ts file.

Expected behavior

The save hook should not be called twice wether we're calling this.model() function with a string or with the name coming from the imported class.

Worse, if we add hooks like NestJS documention suggest, inside module, we should have a way of accessing History Document without triggering the save hook twice.

Package version

10.0.10

mongoose version

8.5.4

NestJS version

10.0.0

Node.js version

18.16.0

In which operating systems have you tested?

Other

No response

kamilmysliwiec commented 1 month ago

The save hook should not be called twice wether we're calling this.model() function with a string or with the name coming from the imported class.

I couldn't reproduce your issue. It fails with either.

Worse, if we add hooks like NestJS documention suggest, inside module, we should have a way of accessing History Document without triggering the save hook twice.

It triggers twice because you insert a test document, and then within a preSave hook a history document with another test document embedded. Once you comment these lines out:

// await historyModel.create({
//   version: 1,
//   test: {
//     title: 'x',
//   },
// });

hook runs only once.

Note: I used the forFeatureAsync (as suggested in the official docs) instead of an inline TestSchema.pre('save', preSaveHook) and it works perfectly fine. There's nothing else we can do on our (NestJS side) to fix this issue as you can reproduce the exact same behavior with pure Mongoose too