MeetJoeBlack
MeetJoeBlack

Reputation: 2924

node.js mongodb .. the (immutable) field '_id' was found to have been altered

I have some problem when I try to upsert my object with new ones(parsed from xml file),but I got the following error:

 MongoError: exception: After applying the update to the document {_id: ObjectId('55be3c8f79bae4f80c6b17f8') , ...}, the (immutable) field '_id' was found to have been altered to _id: ObjectId('55be5f15ae
5597401724aab3')

Here is my code:

xmlFile.product_list.product.forEach(function (product) {

                    var productEntity = new Product({
                        product_id: parseInt(product.id),
                        parent_id: parseInt(product.parent_id),
                        sku: product.sku,
                        title: product.title,
                        pricenormal: parseFloat(product.price_normal),
                        pricewholesale: parseFloat(product.price_wholesale),
                        pricewholesalelarge: parseFloat(product.price_wholesale_large),
                        pricesale: parseFloat(product.price_sale),
                        weight: parseFloat(product.weight),
                        volume: parseFloat(product.volume),
                        unittype: product.unit_type,
                        status: product.status,
                        datecreating: product.datecreating,
                        sp: product.sp,
                        guaranteeext: product.guarantee_ext,
                        used: product.used,
                        statusfull: product.status_full,
                        description: null,
                        url: null
                    });
                    items.push(productEntity);

                });


items.forEach(function (product) { //update or create new products

                    Product.findOneAndUpdate({product_id: product.product_id}, product, {upsert: true}, function (err) {
                        if (err)  return updateDBCallback(err);
                        updateDBCallback(null, 'saved');

                    });

                });

I tried to use hints like:

                //product._id = mongoose.Types.ObjectId(); //doesn't work
                //delete product._id // doesn't delete _id from product

but they didn't help. So I don't want to update my product._id , I just want to update the other fields.

Upvotes: 26

Views: 38234

Answers (5)

Si Zi
Si Zi

Reputation: 1139

C# / .Net

If you are using _user.ReplaceOneAsync(user => user.Id == id, userIn) to update an existing record in the collection then make sure to include the id of the actual record which are updating, leaving it blank means you want it to generate the newGuid for you when it create the new instance of the class.

 public class User
 {
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }
 }

var userCollection = await _claim.FindAsync(user => user.Id == id);
var userToUpdate = userCollection.FirstOrDefault();

//if user exists then provide the same id(primary key) to update the record
User updateUser = new User
{
     Id = userToUpdate.id,   // same id if the class creates one if you dont provide one.
     UserId = "000ef15d8c1ee9cd62699999",
     Email = "email",
}

wait _user.ReplaceOneAsync(user => user.Id == id, updateUser);

Upvotes: 0

Robert
Robert

Reputation: 1362

I got this error (in the Java driver) when my check for an _id was a String instead of an ObjectId.

Wrap your query appropriately:

myCoolCollection.findOneAndUpdate(Filters.eq("_id", new ObjectId(e.id)), ...

Upvotes: 1

thomas
thomas

Reputation: 31

try to use

const product = productEntity.toObject();
...
delete product._id;
...
Product.findOneAndUpdate({product_id: product.product_id}, product)

Upvotes: 3

Bharath T
Bharath T

Reputation: 31

You can use this:

Product.replaceOne({ _id: 55be3c8f79bae4f80c6b17f8}, {                         
   product_id: parseInt(product.id),
   parent_id: parseInt(product.parent_id),
   sku: product.sku,
   title: product.title,
   pricenormal: parseFloat(product.price_normal),
   pricewholesale: parseFloat(product.price_wholesale),
   pricewholesalelarge: parseFloat(product.price_wholesale_large),
   pricesale: parseFloat(product.price_sale),
   weight: parseFloat(product.weight),
   volume: parseFloat(product.volume),
   unittype: product.unit_type,
   status: product.status,
   datecreating: product.datecreating,
   sp: product.sp,
   guaranteeext: product.guarantee_ext,
   used: product.used,
   statusfull: product.status_full,
   description: null,
   url: null});

Upvotes: 3

Alfonso Embid-Desmet
Alfonso Embid-Desmet

Reputation: 3632

When you do new Product(), a new _id is generated, along with other things. Try this:

items.forEach(function (product) { //update or create new products

  // Es6 assign
  var productToUpdate = {};
  productToUpdate = Object.assign(productToUpdate, product._doc);
  delete productToUpdate._id;

  Product.findOneAndUpdate({product_id: product.product_id}, productToUpdate, 
                         {upsert: true}, function (err) {
    if (err)  return updateDBCallback(err);
       updateDBCallback(null, 'saved');

  });

});

Upvotes: 32

Related Questions