Amol M Kulkarni
Amol M Kulkarni

Reputation: 21629

How to get rid of Error: "OverwriteModelError: Cannot overwrite `undefined` model once compiled."?

I have a common method for updating document of any collection in MongoDB?

The following code is in file name Deleter.js

module.exports.MongooseDelete = function (schemaObj, ModelObject);
{
  var ModelObj = new mongoose.Model("collectionName",schemaObj);
  ModelObj.remove(ModelObject);
}

And invoking as follows in my main file app.js:

var ModObj = mongoose.model("schemaName", schemasObj);
var Model_instance = new ModObj();
var deleter = require('Deleter.js');
deleter.MongooseDelete(schemasObj,Model_instance);

I am getting following error:

OverwriteModelError: Cannot overwrite `undefined` model once compiled.
    at Mongoose.model (D:\Projects\MyPrjct\node_modules\mongoose\lib\index.js:4:13)

I get on 2nd method call only.. Please let me know if any one has got some solution.

Upvotes: 27

Views: 43281

Answers (8)

Davi Artur
Davi Artur

Reputation: 51

The problem itself is to create models with the same name, when we pass "user" as first argument we are defining only the name of the model, NOT that of the collection

ex: mongoose.model("cadastry", cadastryUserSchema, "users")

ex: mongoose.model(nameModel, SchemaExample, NameQueyCollection)

TypeScript info name: string, schema?: mongoose.Schema<...> | undefined, collection?: string | undefined

Upvotes: 0

fruitloaf
fruitloaf

Reputation: 2862

mine got solved with this code:

  module.exports = mongoose.models.nameOne || mongoose.model('nameOne', PostSchema);

Upvotes: 1

DavidLee
DavidLee

Reputation: 63

This is because require one Model in two paths.

// Comment Model file

var mongoose = require('mongoose')
var Schema = mongoose.Schema

var CommentSchema = Schema({
  text: String,
  author: String
})

module.exports = mongoose.model('Comment', CommentSchema)

// Seed file

const commentData = {
  user: "David Lee",
  text: "This is one comment"
}
var Comment = require('./models/Comment')

module.exports = function seedDB () {
  Comment.create(commentData, function (err, comment) {
    console.log(err, commemt)
  })
}

// index file

var Comment = require('./models/comment')
var seedDB = require('./seeds')
seedDB()
const comment = {
  text: 'This girl is pretty!',
  author: 'David'
}
Comment.create(, function (err, comment) {
    console.log(err, comment)
 })

Now you will get throw new mongoose.Error.OverwriteModelError(name), Cuz you require Comment model in two different ways. Seed file var Comment = require('./models/Comment'),Index file var Comment = require('./models/comment')

Upvotes: 1

Nikolay Stavrev
Nikolay Stavrev

Reputation: 51

Actually the problem is not that mongoose.model() is instantiated twice. The problem is that the Schema is instantiated more than one time. For example if you do mongoose.model("Model", modelSchema) n times and you are using the same reference to the Schema this would not be a problem for mongoose. The problem comes when you use another reference of schema on the same model i.e

var schema1 = new mongoose.Schema(...);
mongoose.model("Model", schema1);
mongoose.model("Model", schema2);

This is the situation when this error occurs.

If you look at the source (mongoose/lib/index.js:360) this is the check

if (schema && schema.instanceOfSchema && schema !== this.models[name].schema){
    throw new mongoose.Error.OverwriteModelError(name);
}

Upvotes: 5

paulbjensen
paulbjensen

Reputation: 838

I managed to resolve the problem like this:

var Admin;

if (mongoose.models.Admin) {
  Admin = mongoose.model('Admin');
} else {
  Admin = mongoose.model('Admin', adminSchema);
}

module.exports = Admin;

Upvotes: 53

hotienvu
hotienvu

Reputation: 685

I think you have instantiated mongoose.Model() on the same schema twice. You should have created each model only once and have a global object to get a hold of them when need

I assume you declare different models in different files under directory $YOURAPP/models/

$YOURAPPDIR/models/
 - index.js
 - A.js
 - B.js

index.js

module.exports = function(includeFile){
    return require('./'+includeFile);
};

A.js

module.exports = mongoose.model('A', ASchema);

B.js

module.exports = mongoose.model('B', BSchema);

in your app.js

APP.models = require('./models');  // a global object

And when you need it

// Use A
var A = APP.models('A');
// A.find(.....

// Use B
var B = APP.models('B');
// B.find(.....

Upvotes: 37

Kavi
Kavi

Reputation: 174

I found it better to avoid global and exception handing-

var mongoose = require("mongoose");
var _ = require("underscore");

var model;
if (_.indexOf(mongoose.modelNames(), "Find")) {
    var CategorySchema = new mongoose.Schema({
        name: String,
        subCategory: [
            {
                categoryCode: String,
                subCategoryName: String,
                code: String
            }
        ]
    }, {
        collection: 'category'
    });
    model = mongoose.model('Category', CategorySchema);
}
else {
    model = mongoose.model('Category');
}


module.exports = model;

Upvotes: 3

user1082679
user1082679

Reputation:

I try to avoid globals as much as possible, since everything is by reference, and things can get messy. My solution

model.js

  try {
    if (mongoose.model('collectionName')) return mongoose.model('collectionName');
  } catch(e) {
    if (e.name === 'MissingSchemaError') {
       var schema = new mongoose.Schema({ name: 'abc });
       return mongoose.model('collectionName', schema);
    }
  }

Upvotes: 10

Related Questions