diff --git a/lib/drivers/node-mongodb-native/collection.js b/lib/drivers/node-mongodb-native/collection.js index ae74dd1a880..5c5dd538e68 100644 --- a/lib/drivers/node-mongodb-native/collection.js +++ b/lib/drivers/node-mongodb-native/collection.js @@ -43,11 +43,9 @@ Object.setPrototypeOf(NativeCollection.prototype, MongooseCollection.prototype); */ NativeCollection.prototype.onOpen = function() { - const _this = this; - - _this.collection = _this.conn.db.collection(_this.name); - MongooseCollection.prototype.onOpen.call(_this); - return _this.collection; + this.collection = this.conn.db.collection(this.name); + MongooseCollection.prototype.onOpen.call(this); + return this.collection; }; /** @@ -60,6 +58,25 @@ NativeCollection.prototype.onClose = function(force) { MongooseCollection.prototype.onClose.call(this, force); }; +/** + * Helper to get the collection, in case `this.collection` isn't set yet. + * May happen if `bufferCommands` is false and created the model when + * Mongoose was disconnected. + * + * @api private + */ + +NativeCollection.prototype._getCollection = function _getCollection() { + if (this.collection) { + return this.collection; + } + if (this.conn.db != null) { + this.collection = this.conn.db.collection(this.name); + return this.collection; + } + return null; +}; + /*! * ignore */ @@ -74,7 +91,7 @@ const syncCollectionMethods = { watch: true, find: true, aggregate: true }; function iter(i) { NativeCollection.prototype[i] = function() { - const collection = this.collection; + const collection = this._getCollection(); const args = Array.from(arguments); const _this = this; const globalDebug = _this && diff --git a/test/connection.test.js b/test/connection.test.js index fcb78b7fc95..2512ffb02db 100644 --- a/test/connection.test.js +++ b/test/connection.test.js @@ -1495,4 +1495,23 @@ describe('connections:', function() { assert.equal(m.connection.model('Test2'), Test2); }); + + it('creates collection if creating model while connection is disconnected with bufferCommands=false', async function() { + const m = new mongoose.Mongoose(); + m.set('bufferCommands', false); + const conn = await m.createConnection(start.uri, { bufferCommands: false }).asPromise(); + conn.client.emit('serverDescriptionChanged', { newDescription: { type: 'Unknown' } }); + + const Test = conn.model('Test', new Schema({ name: String })); + + const [res] = await Promise.all([ + Test.findOne().exec(), + new Promise.resolve(resolve => setTimeout(resolve, 100)).then(() => { + conn.client.emit('serverDescriptionChanged', { newDescription: { type: 'Single' } }); + }) + ]); + assert.equal(res, null); + + await m.disconnect(); + }); });