From 344d8e72986148c54296ceb9e826e4edee5a08f8 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Fri, 28 Nov 2025 12:57:28 -0500 Subject: [PATCH 1/2] fix(model): bump version if necessary after successful bulkSave() Fix #15800 --- lib/document.js | 16 ++++++++++++++++ lib/model.js | 13 +++++-------- test/model.test.js | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/lib/document.js b/lib/document.js index 15764c7568..cd0ca2d326 100644 --- a/lib/document.js +++ b/lib/document.js @@ -5422,6 +5422,22 @@ Document.prototype.$__hasOnlyPrimitiveValues = function $__hasOnlyPrimitiveValue })); }; +/*! + * Increment this document's version if necessary. + */ + +Document.prototype._applyVersionIncrement = function _applyVersionIncrement() { + if (!this.$__.version) return; + const doIncrement = VERSION_INC === (VERSION_INC & this.$__.version); + + this.$__.version = undefined; + if (doIncrement) { + const key = this.$__schema.options.versionKey; + const version = this.$__getValue(key) || 0;// increment version if was successful + this.$__setValue(key, version + 1); + } +}; + /*! * Module exports. */ diff --git a/lib/model.js b/lib/model.js index 67f017b6a4..e7247344a5 100644 --- a/lib/model.js +++ b/lib/model.js @@ -523,11 +523,9 @@ Model.prototype.$__save = function(options, callback) { const versionBump = this.$__.version; // was this an update that required a version bump? if (versionBump && !this.$__.inserting) { - const doIncrement = VERSION_INC === (VERSION_INC & this.$__.version); - this.$__.version = undefined; - const key = this.$__schema.options.versionKey; - const version = this.$__getValue(key) || 0; if (numAffected <= 0) { + const key = this.$__schema.options.versionKey; + const version = this.$__getValue(key) || 0; // the update failed. pass an error back this.$__undoReset(); const err = this.$__.$versionError || @@ -535,10 +533,7 @@ Model.prototype.$__save = function(options, callback) { return callback(err, this); } - // increment version if was successful - if (doIncrement) { - this.$__setValue(key, version + 1); - } + this._applyVersionIncrement(); } if (result != null && numAffected <= 0) { this.$__undoReset(); @@ -3666,6 +3661,8 @@ function handleSuccessfulWrite(document) { } document.$__reset(); + document._applyVersionIncrement(); + document.schema.s.hooks.execPost('save', document, [document], {}, (err) => { if (err) { reject(err); diff --git a/test/model.test.js b/test/model.test.js index cb28be62aa..264e59f90a 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -7015,6 +7015,53 @@ describe('Model', function() { ); }); + it('increments version key on successful save (gh-15800)', async function() { + // Arrange + const userSchema = new Schema({ + name: [String], + email: { type: String, minLength: 3 } + }); + + const User = db.model('User', userSchema); + const user1 = new User({ name: ['123'], email: '12314' }); + await user1.save(); + + // Act + const user = await User.findOne({ _id: user1._id }); + assert.ok(user); + + // Before, __v should be 0 + assert.equal(user.__v, 0); + + // markModified on array field (triggers $set) + user.markModified('name'); + await User.bulkSave([user]); + + const dbUser1 = await User.findById(user._id); + assert.equal(dbUser1.__v, 1); + assert.equal(user.__v, 1); + + // Update another path and markModified + user.email = '1375'; + await User.bulkSave([user]); + const dbUser2 = await User.findById(user._id); + assert.equal(dbUser2.__v, 1); + assert.equal(user.__v, 1); + + let reloaded = await User.findById(user._id); + assert.equal(reloaded.__v, 1); + + user.email = '1'; + await assert.rejects( + () => User.bulkSave([user]), + /email.*is shorter than the minimum allowed length/ + ); + assert.equal(user.__v, 1); + + reloaded = await User.findById(user._id); + assert.equal(reloaded.__v, 1); + }); + it('saves new documents with ordered: false (gh-15495)', async function() { const userSchema = new Schema({ name: { type: String } From 7a305a8b5b60437714a5110fae8ddb34e6ed679c Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Mon, 1 Dec 2025 17:37:36 -0500 Subject: [PATCH 2/2] Update lib/document.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- lib/document.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/document.js b/lib/document.js index cd0ca2d326..e9b1e63e90 100644 --- a/lib/document.js +++ b/lib/document.js @@ -5433,8 +5433,8 @@ Document.prototype._applyVersionIncrement = function _applyVersionIncrement() { this.$__.version = undefined; if (doIncrement) { const key = this.$__schema.options.versionKey; - const version = this.$__getValue(key) || 0;// increment version if was successful - this.$__setValue(key, version + 1); + const version = this.$__getValue(key) || 0; + this.$__setValue(key, version + 1); // increment version if was successful } };