Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose: Incrementing my documents version number doesn't work, and I'm getting a Version Error when I try to save

When I try to save my document, I'm getting a VersionError: No matching document found error, similar to this SO question.

After reading this blog post, it seems that the problem is with the versioning of my document. That I'm messing with an array and so I need to update the version.

However, calling document.save() doesn't work for me. When I log out the document before and after the call to save(), document._v is the same thing.

I also tried doing document._v = document._v++ which also didn't work.


Code

exports.update = function(req, res) {
  if (req.body._id) { delete req.body._id; }
  User.findById(req.params.id, function(err, user) {
    if (err) return handleError(res, err);
    if (!user) return res.send(404);
    var updated = _.extend(user, req.body); // doesn't increment the version number. causes problems with saving. see http://aaronheckmann.blogspot.com/2012/06/mongoose-v3-part-1-versioning.html
    console.log('pre increment: ', updated);
    updated.increment();
    // updated._v = updated._v++;
    console.log('post increment: ', updated);
    updated.save(function(err) {
      if (err) return handleError(res, err);
      return res.json(200, user);
    });
  });
};

Output

pre increment:  { _id: 5550baae1b571aafa52f070c,
  provider: 'local',
  name: 'Adam',
  email: '[email protected]',
  hashedPassword: '/vahOqXwCwKQKtcV3KBQeFge/YB0xtqOj+YDyck7gzyALA/IP7u7BfqQhlVHBQT26//XfBTkaOCK2bQXg65OzA==',
  salt: 'MvzXW7D4xuyGQBJNeFRoUg==',
  __v: 32,
  drafts: [],
  starredSkims: [],
  skimsCreated: [ 5550cfdab8dcacd1a7892aa4 ],
  role: 'user' }

post increment:  { _id: 5550baae1b571aafa52f070c,
  provider: 'local',
  name: 'Adam',
  email: '[email protected]',
  hashedPassword: '/vahOqXwCwKQKtcV3KBQeFge/YB0xtqOj+YDyck7gzyALA/IP7u7BfqQhlVHBQT26//XfBTkaOCK2bQXg65OzA==',
  salt: 'MvzXW7D4xuyGQBJNeFRoUg==',
  __v: 32,
  drafts: [],
  starredSkims: [],
  skimsCreated: [ 5550cfdab8dcacd1a7892aa4 ],
  role: 'user' }
like image 528
Adam Zerner Avatar asked Sep 27 '22 23:09

Adam Zerner


1 Answers

The issue here has to do with using __v and trying to update it manually. .increment does not actually perform an increment immediately, but it does set an internal flag for the model to handle incrementing. I can't find any documentation on .increment, so I assume it is probably for use internally. The problem stems from trying to combine .extend with an object that already has __v (there are two underscores by the way, not that document.__v++ affects the model internally anyway) in addition to using .increment.

When you use _.extend it copies the __v property directly onto the object which seems to cause problems because Mongoose cannot find the old version internally. I didn't dig deep enough to find why this is specifically, but you can get around it by also adding delete req.body.__v.

Rather than finding and saving as two steps, you can also use .findByIdAndUpdate. Note that this does not use __v or increment it internally. As the other answer and linked bug indicate, if you want to increment the version during an update you have to do so manually.

like image 155
Explosion Pills Avatar answered Oct 20 '22 04:10

Explosion Pills