node-orm2 icon indicating copy to clipboard operation
node-orm2 copied to clipboard

Saving an instance fails if a prior save had no changes

Open EisFrei opened this issue 8 years ago • 3 comments

There are no errors and yet the database is not updated. Some stored 'unchanged' flag may prevent the update.

I have attached an example that results in:

"third","1"
"first","2"
"first","3"

When the result should be:

"third","1"
"third","2"
"third","3"

Example

var orm = require('orm');
var async = require('async');

orm.connect("mysql://test:test@localhost/test?debug=true", function(err, db) {
    if (err) throw err;
    var Person = db.define("person", {
        name: String,
    });

    db.sync(function(err) {
        if (err) throw err;

        async.series([
            function(done) {

                // create a person and change the name each time.
                // this works.
                Person.create({
                    name: 'first',
                }, function(err, person) {
                    Person.get(person.id, function(err, person) {
                        if (err) throw err;

                        // rename the person

                        person.name = 'second';
                        person.save(function(err, person) {
                            if (err) throw err;
                            person.name = 'third';
                            person.save(function(err, person) {
                                if (err) throw err;
                                console.log('created and saved', person.id, person.name);
                                done(err, person);
                            });
                        });
                    });
                });
            },
            function(done) {

                // create a person and set the original name again before first save.
                // this does not update the user on both saves.
                Person.create({
                    name: 'first',
                }, function(err, person) {
                    Person.get(person.id, function(err, person) {
                        if (err) throw err;

                        // set name again

                        person.name = 'first';
                        person.save(function(err, person) {
                            if (err) throw err;
                            person.name = 'third';
                            person.save(function(err, person) {
                                if (err) throw err;
                                console.log('created and saved', person.id, person.name);
                                done(err, person);
                            });
                        });
                    });
                });
            },
            function(done) {

                // create a person and don't change anything before first save
                // this does not update the user on both saves.
                Person.create({
                    name: 'first',
                }, function(err, person) {
                    Person.get(person.id, function(err, person) {
                        if (err) throw err;

                        // don't change anything

                        person.save(function(err, person) {
                            if (err) throw err;
                            person.name = 'third';
                            person.save(function(err, person) {
                                if (err) throw err;
                                console.log('created and saved', person.id, person.name);
                                done(err, person);
                            });
                        });
                    });
                });
            }

        ], function(err, data) {
            console.log('done',err);
        });
    });
});

Log output

(orm/mysql) SHOW TABLES LIKE 'person'
(orm/mysql) CREATE TABLE `person` (`name` VARCHAR(255), `id` INT(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`))
(orm/mysql) INSERT INTO `person` (`name`, `id`) VALUES ('first', NULL)
(orm/mysql) SELECT `name`, `id` FROM `person` WHERE `id` = 1 LIMIT 1
(orm/mysql) UPDATE `person` SET `name` = 'second' WHERE `id` = 1
(orm/mysql) UPDATE `person` SET `name` = 'third' WHERE `id` = 1
created and saved 1 third
(orm/mysql) INSERT INTO `person` (`name`, `id`) VALUES ('first', NULL)
(orm/mysql) SELECT `name`, `id` FROM `person` WHERE `id` = 2 LIMIT 1
created and saved 2 third
(orm/mysql) INSERT INTO `person` (`name`, `id`) VALUES ('first', NULL)
(orm/mysql) SELECT `name`, `id` FROM `person` WHERE `id` = 3 LIMIT 1
created and saved 3 third
done

System

Tested in node v0.10.32 (system) and v5.7.0 (nvm) on an up to date Linux Mint 17.3 Rosa.

Packages:

+-- [email protected]
+-- [email protected]
| +-- [email protected]
| `-- [email protected]
|   +-- [email protected]
|   +-- [email protected]
|   +-- [email protected]
|   `-- [email protected]
`-- [email protected]
  +-- [email protected]
  +-- [email protected]
  +-- [email protected]
  +-- [email protected]
  +-- [email protected]
  `-- [email protected]

EisFrei avatar Mar 02 '16 21:03 EisFrei

What version of MySQL are you running?

nallown avatar Mar 14 '16 03:03 nallown

mysql Ver 14.14 Distrib 5.5.47, for debian-linux-gnu (x86_64) using readline 6.3

EisFrei avatar Mar 14 '16 09:03 EisFrei

I can confirm the described outcome, so I checked a few different versions. The current orm release was tested with nodejs v5.9.1 and v0.12.2 (Linux Mint package), older ones only on 5.9.1.

I have tried the snippet above with the following orm versions:

  • 2.1.30 FAIL
  • 2.1.29 FAIL
  • 2.1.20 FAIL
  • 2.1.10 FAIL
  • 2.1.9 FAIL
  • 2.1.8 FAIL
  • 2.1.7 FAIL
  • 2.1.6 FAIL
  • 2.1.5 FAIL
  • 2.1.4 FAIL
  • 2.1.3 PASS
  • 2.1.2 PASS
  • 2.1.1 PASS
  • 2.1.0 PASS

My MySQL is nearly the same version: mysql Ver 14.14 Distrib 5.6.28, for debian-linux-gnu (x86_64) using EditLine wrapper.

jgibbon avatar Mar 24 '16 03:03 jgibbon