-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Edge case where SingleNested value update is not marked as changed and saving fails to update #9208
Labels
confirmed-bug
We've confirmed this is a bug in Mongoose and will fix it.
Milestone
Comments
Here's even simpler reproduction code: import mongoose from "mongoose";
const TestModel = mongoose.model('Test', new mongoose.Schema({
nested: new mongoose.Schema({
type: {myArray: [String]},
default: {}
})
}));
(async function run() {
const test = new TestModel();
test.nested = {myArray: ["Test"]}
await test.save();
// DB now has: {nested: {myArray: ["test"]}}
test.nested.myArray = []; // Mongoose cannot detect this change
await test.save();
// DB still has: {nested: {myArray: ["test"]}}
await test.remove();
})().then(() => process.exit()); Why it happens in this case:
|
vkarpov15
added a commit
that referenced
this issue
Jul 11, 2020
Thanks for reporting this issue, this is a bug in Mongoose. |
Glad to hear it's a simple fix! And glad to help :) |
vkarpov15
added a commit
that referenced
this issue
Jul 25, 2020
vkarpov15
added a commit
that referenced
this issue
Jul 28, 2020
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The bug
I've found a case where Mongoose's change tracking fails entirely.
Here's the simplest example I could create to reproduce the issue:
Here's the log output of running this code:
Note the 3rd line where Mongoose fails updating
myBool = true
Why this is happening
I've found is that this is happening because each time a SingleNested doc is cast by setting it to an object which contains at least one key - then the existing value for that SingleNested is recorded as the "priorDoc". This happens here:
mongoose/lib/schema/SingleNestedPath.js
Lines 177 to 181 in a3f61ad
And when setting a value, Mongoose looks at this
priorDoc
to see if it contains a matching value to the one that's currently being set. So if you set a value to the same value that was in thepriorDoc
, then it doesn't consider this to be a change. This happens here:mongoose/lib/document.js
Lines 1121 to 1134 in a3f61ad
Workaround
While a fix for this is unavailable, there is a reasonably simple workaround. Never set a nested document to an object other than an empty object literal. Doing this will ensure that the
priorDoc
is not kept in memory.Version stuff
mongoose: 5.9.21
Node.js: 14.3.0
MongoDB: 4.0.3
The text was updated successfully, but these errors were encountered: