dresende / node-orm2

Object Relational Mapping
http://github.com/dresende/node-orm2
MIT License
3.07k stars 376 forks source link

.save() updates twice, reverts first update #298

Open SamuelBolduc opened 11 years ago

SamuelBolduc commented 11 years ago

Somewhat related with https://github.com/dresende/node-orm2/issues/258 but causes a bug in this case When I saving a model, if I change the association, I do something like this to change it :

req.models.object.get(req.params.id, function(err, employee) {
  employee.object_subtype_id = 1;
  employee.save(function(err) {
    console.log(err);
    res.send('OK');
  });
});

But when I reload, it seems like the value has not changed. After enabling query debug, I see this :

[SQL/postgres] UPDATE "object" SET "object_subtype_id" = 1 WHERE "id" = 2
[SQL/postgres] UPDATE "object" SET "object_subtype_id" = 2 WHERE "id" = 2

So for some reason it updates twice the same row, and the second update reverts the first one..

dresende commented 11 years ago

Please try the latest commit. We've been working on some related issues.

SamuelBolduc commented 11 years ago

Do I have to apply them manually (cause there are a lot of commits for yesterday) or I can just npm install dresende/node-orm2?

notheotherben commented 11 years ago

You should be able to npm install dresende/node-orm2 without any problems.

SamuelBolduc commented 11 years ago

RangeError: Maximum call stack size exceeded - With the latest code in the repository (using npm install dresende/node-orm2)

Debugging (only the first UPDATE query is valid for what I want to do):

[SQL/postgres] UPDATE "object" SET "object_subtype_id" = 2 WHERE "id" = 1
[SQL/postgres] UPDATE "object" SET "object_subtype_id" = 1 WHERE "id" = 1
[SQL/postgres] UPDATE "object" SET "object_subtype_id" = 1 WHERE "id" = 1
[SQL/postgres] UPDATE "object" SET "object_subtype_id" = 1 WHERE "id" = 1
[SQL/postgres] UPDATE "object" SET "object_subtype_id" = 1 WHERE "id" = 1

/var/www/project/node_modules/pg/lib/client.js:160
      throw error;
            ^
RangeError: Maximum call stack size exceeded
``` 
dresende commented 11 years ago

Does this still happen?

goulwenlorcy commented 11 years ago

Issue #279 is resolved thank you, no Stack overflow or RangeError but I have the same revert update problem with the latest commit:

Log SQL:

| UPDATE `permissions` SET `sensors_id` = 4 WHERE `id` = 10
| UPDATE `permissions` SET `sensors_id` = 3 WHERE `id` = 10
| UPDATE `permissions` SET `sensors_id` = 3 WHERE `id` = 10

(Good update is: sensors_id = 4)

With:

this.models.permissions.get(uid, function (err, item) {
               item.save(arg, function (err) {
                 callback(null, {query: "Put OK"});    
                });       
            });
db.define("permissions", {}, { autoFetch : true },
    { methods: {},  validations: {}  });
models.permissions = db.models.permissions;
models.permissions.hasOne('possess', models.possess, { required: true });
models.permissions.hasOne('sensors', models.sensors, { required: true });
models.permissions.hasOne('rules', models.rules, { required: true });
dresende commented 11 years ago

Can you please test again?

goulwenlorcy commented 11 years ago

No, always the same problem,

With a console.log on getinstancedata() in instance.js/saveinstance function:

I have 7 calls:

{ id: 10, possess_id: 1, sensors_id: 4, rules_id: 3 }    ---> Permissions table (new values)
{ id: 1,  
  validityBegin: Mon Aug 05 2013 07:25:00 GMT+0200 (CEST),
  validityEnd: Tue Aug 06 2013 08:25:00 GMT+0200 (CEST),
  members_id: 1,
  swipercards_id: 4 }                                    ---> Possess table (no modification)
{ id: 10, possess_id: 1, sensors_id: 4, rules_id: 3 }    ---> Permissions table (new values) 
{ id: 3, ipadress: '10.1.1.1', location: 'loca' }        ---> Sensors table (old values)
{ id: 10, possess_id: 1, sensors_id: 3, rules_id: 3 }    ---> Permissions table (sensors_id old value)
{ id: 2,
  validityBegin: Mon Aug 05 2013 15:25:59 GMT+0200 (CEST),
  validityEnd: Thu Aug 15 2013 09:30:59 GMT+0200 (CEST) }---> Rules table (old values)
{ id: 10, possess_id: 1, sensors_id: 3, rules_id: 2 }    ---> Permissions table (sensors_id & rules_id old values)

Old Permissions & Rules objects revert IDs modifications?

dresende commented 11 years ago

Please post a short example showing this. And make sure you're trying 2.1.2 :)

goulwenlorcy commented 11 years ago

Below, a short full example with the bug.

In the app.get("/test" ...) function: Save work for item.value but not for item.members_id (I think the "members" object revert the members_id modification)

You can test and run this code on cloud9: https://c9.io/gobzh/orm

I'm trying with 2.1.3 :) Thanks for your help


var express = require('express');
var orm = require('orm');
var app = express();

app.use(orm.express("mysql path", {
    define: function (db, models) {

            db.load("./models/membersModel", function (err) {
                models.members = db.models.members;
                db.models.members.sync(function (err) {
                !err && console.log("done members!");
                });
            });

            db.load("./models/possessModel", function (err) {
                models.possess = db.models.possess;
                models.possess.hasOne('members', models.members, { required: true });
                db.models.possess.sync(function (err) {
                    !err && console.log("done possess!");
                });             
            });
        }
}));
app.listen(process.env.PORT);

app.get("/test", function (req, res) {
   res.writeHead(200, { 'Content-Type': 'application/json' });

   req.models.possess.get(1, function (err, item) {
        item.members_id = 2; 
        item.value = 22;
        item.save(function (err) {
        res.end(JSON.stringify({query: "Put OK"})); 
        }); 

    });
});

app.get("/", function (req, res) {
   res.writeHead(200, { 'Content-Type': 'application/json' });

   req.models.possess.find({id: 1}, function (err, items) {    
        if(err)
            res.end(JSON.stringify({query: "Get Fail", err: err}));
        else
            res.end(JSON.stringify(items));                
    });  
});

membersModel.js

module.exports = function (db, cb) {
db.define("members", {
        familyname  : String,
        firstname   : String,
    }, 
    {
        methods: {
            fullName: function () {
                return this.name + ' ' + this.surname;
            }
        },
        validations: {

        }
    });
    return cb();
}

possessModel.js

module.exports = function (db, cb) {
db.define("possess", {
         test   : String,
        value   : Number,     
    }, {  autoFetch : true
},
    {
        methods: {

        },
        validations: {

        }
    });
    return cb();
}
goulwenlorcy commented 11 years ago

A temporary solution: In lib/instance.js/saveInstance, I set the saveOptions.saveAssociations always false. and in my project , I set the "instance.cache" to false.

ralfschimmel commented 10 years ago

I agree with @goulwenlorcy it is saved twice, also when using current master. I needed to pass the {saveAssociations: false} as argument to the save() method to prevent this strange double update. Any plans to fix this?

Lao-Ben commented 10 years ago

Same problem here on 2.1.18