0

I have stripped down my application and database context to the simplest bits. I have two tables, Maps and Markers. Many Markers exist for each map. With an existing Map, I can't seem to insert new Markers; I am getting the default error callback.

Tracing through the jaydata.js, I am getting an error in the SqLiteProvider.js file, in the exec function. It is an SQL failure, and is attempting to insert the Map (with the primary key set) into the table, which fails. What am I doing wrong?

My Context:

$data.Entity.extend("$org.types.Marker", {
    Id: { type: "int", key: true, computed: true },
    Left: { type: "int", required: true },
    Top: { type: "int", required: true },
    Color: { type: "string", required: true },
    Name: { type: "string", required: true },
    Map: { type: "$org.types.Map", inverseProperty: "Markers" }
});


$data.Entity.extend("$org.types.Map", {
    Id: { type: "int", key: true, computed: true },
    Title: { type: "string", required: true },
    Src: { type: "string", required: true },
    Height: { type: "int", required: true },
    Width: { type: "int", required: true },
    Markers: { type: "Array", elementType: "$org.types.Marker", inverseProperty: "Map" }
});

$data.EntityContext.extend("$org.types.OrgContext", {
    Maps: { type: $data.EntitySet, elementType: $org.types.Map },
    Markers: { type: $data.EntitySet, elementType: $org.types.Marker },
 });

var DB = new $org.types.OrgContext({ name: "webSql", databaseName: "Testing"});

My test code:

DB.Maps.single( function (map) { return map.Id == 1; }, {}, function(map) {
        var marker = new $org.types.Marker({
            Left: 250,
            Top: 350,
            Color: 'green',
            Name: 'Example',
            Map: map});

        DB.Markers.add(marker);
        DB.saveChanges(function() {
            alert(marker.Id);
        });

    });
Adam Casey
  • 949
  • 2
  • 8
  • 24

1 Answers1

1

The example doesn't insert the map object. This is not a problem if you already have it.

There is a general problem, which is forgotten many times: the context.onReady() should be used before accessing data with the provider.

This won't solve the problem per se, there is one line should be added before saving the ne marker object:

DB.Maps.attach(map);

This is necessary to move the object to the scope of the context and set the entityState property of the map to $data.EntityState.Unchanged. If you read an entity from the DB, the entityState will be unknown, and the provider tries to save it as a new record. Trying to saving the map entity as a new record caused an SQL error, because there was an existing record with ID=1.

The updated code looks like bellow:

var DB = new $org.types.OrgContext({ name: "webSql", databaseName: "Testing" });

        DB.onReady(function () {
            DB.Maps.single(function (map) { return map.Id == 1; }, {}, function (map) {
                DB.Maps.attach(map); //this sets map.entityState = $data.EntityState.Unchanged;
                var marker = new $org.types.Marker({
                    Left: 250,
                    Top: 350,
                    Color: 'green',
                    Name: 'Example',
                    Map: map
                });
                DB.Markers.add(marker);
                DB.saveChanges(function () {
                    alert(marker.Id)
                });
            });
        });

UPDATE: if you save a new Maker with a new Map entity, there is no need to attach, and your code needs only the DB.onReady()

Robesz
  • 1,646
  • 11
  • 13
  • Thanks; the critical piece was the `attach()`. Thanks as well for the explanation of the entityState property - that makes total sense. I would add that the documentation is pretty light on the `context.onReady()` - I have been scouring JayData documentation for a few weeks now and this is the first that I have read about that! – Adam Casey Feb 08 '13 at 14:50
  • Thank you for your feedback, I must totally agree with you on the documentation and we began to improve this on the website. – Robesz Feb 08 '13 at 16:28
  • That's great. I think JayData is a really useful ORM, and am enjoying using it. – Adam Casey Feb 08 '13 at 18:31
  • @Robesz everybody is suffering with the docs and few examples of jaydata usage. This is a powerful tool but people have to know how to use it. BTW, please look at my most recent question about it. I'm in a need of some directions in jay data.. Thank you. – DontVoteMeDown Aug 01 '13 at 13:30
  • @DontVodeMeDown: you can find more examples here: http://jaydata.org/examples . This is the first time I hear everybody's suffer with the docs, please pose specific questions and the team will help you. – Robesz Aug 06 '13 at 05:44