Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validation error using `create()` in Mongoose transaction

I'm testing transactions using mongoose and trying to accomplish a very simple task with the following code:

      const session = await mongoose.startSession();
      session.startTransaction();
      try {
        const opts = { session, new: true };
        const A = await Author.
        create({
          firstName: 'Jon',
          lastName: 'Snow'}, session);
        if(!A) throw new Error('Aborted A by Amit!');
        const B = await Author.
        findOneAndUpdate({firstName: 'Bill'}, {firstName: 'William'}, opts);
        if(!B) throw new Error('Aborted B by Amit!');
        await session.commitTransaction();
        session.endSession();
      } catch (err) {
        await session.abortTransaction();
        session.endSession();
        throw err;
      }

All I'm trying to do is first insert (using mongoose create() method) a new document into a collection and then edit (using Mongo findOneAndUpdate() method) another document in the same collection. Failure of either query needs to abort the entire transaction suite.

It's the create() that seems to be giving me problems. The document does get created and inserted, however, it also throws an error:

"Author validation failed: lastName: Path lastName is required., firstName: Path firstName is required."

Any idea what this could mean? It seems it's complaining about not being given values for required fields (firstName and lastName) despite me having already given it those.

like image 877
TheLearner Avatar asked Aug 24 '26 19:08

TheLearner


1 Answers

I have no idea why it would complain about missing values when I've provided them both and they're still getting added to the collection!

This is because Model.create() first parameters accept documents to insert, as an array OR as a spread. For example, these two are equivalent:

// pass a spread of docs
Candy.create({ type: 'jelly bean' }, { type: 'snickers' }) 

// pass an array of docs 
Candy.create([{ type: 'jelly bean' }, { type: 'snickers' }])

The problem with your line, is that it's trying to take the second document {session: session} as another entry for Author, which is missing the required firstName and lastName fields.

Instead you should do:

Author.create([{ firstName: 'Quentin', lastName: 'Tarantino' }], 
               { session: session }
);

You may also find Transactions in Mongoose a helpful reference.

like image 144
Wan Bachtiar Avatar answered Aug 26 '26 17:08

Wan Bachtiar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!