Manipulating and persisting objects

Creating and manipulating objects

New objects can be instantiated with the constructor functions returned from persistence.define calls. Optionally, an object with initial property values can be passed as well, or the properties may be set later.:

var task = new Task();
var category = new Category({name: "My category"});
category.metaData = {rating: 5};
var tag = new Tag();
tag.name = "work";

In server-environments, a Session object must be passed to entity constructors, as follows:

var task = new Task(session);
var category = new Category(session, {name: "My category"});
category.metaData = {rating: 5};
var tag = new Tag(session);
tag.name = "work";

Many-to-one relationships are accessed using their specified name, e.g.:

task.category = category;

One-to-many and many-to-many relationships are access and manipulated through the QueryCollection API:

task.tags.add(tag);
tasks.tags.remove(tag);
tasks.tags.list(tx, function(allTags) { console.log(allTags); });

Entity objects

Entity instances also have a few predefined properties and methods you should be aware of:

  • obj.id, contains the identifier of your entity, this is a automatically generated (approximation of a) UUID. You should never write to this property.
  • obj.fetch(prop, callback), if an object has a hasOne relationship to another which has not yet been fetched from the database (e.g. when prefetch wasn’t used), you can fetch in manually using fetch. When the property object is retrieved the callback function is invoked with the result, the result is also cached in the entity object itself.
  • obj.selectJSON([tx], propertySpec, callback), sometime you need to extract a subset of data from an entity. You for instance need to post a JSON representation of your entity, but do not want to include all properties. selectJSON allows you to do that. The propertySpec arguments expects an array with property names. Some examples:
    • ['id', 'name'], will return an object with the id and name property of this entity
    • ['*'], will return an object with all the properties of this entity, not recursive
    • ['project.name'], will return an object with a project property which has a name property containing the project name (hasOne relationship)
    • ['project.[id, name]'], will return an object with a project property which has an id and name property containing the project name (hasOne relationship)
    • ['tags.name'], will return an object with an array tags property containing objects each with a single property: name
See also  AppEngine Datastore Setup

Persisting/removing objects

Similar to hibernate, persistence.js uses a tracking mechanism to determine which objects’ changes have to be persisted to the database. All objects retrieved from the database are automatically tracked for changes. New entities can be tracked to be persisted using the persistence.add/session.add function:

var c = new Category({name: "Main category"});
persistence.add(c);
for ( var i = 0; i < 5; i++) {
  var t = new Task();
  t.name = 'Task ' + i;
  t.done = i % 2 == 0;
  t.category = c;
  persistence.add(t);
}

Objects can also be removed from the database using the remove() function on either the persistence (client-side) or session (server-side) object:

persistence.remove(c);

All changes made to tracked objects can be flushed to the database by using flush, which optionally takes a transaction object and callback function as arguments. A new transaction can be started using transaction. Again, in the client these functions are called on persistence, on the server they are called on session:

persistence.transaction(function(tx) {
  persistence.flush(tx, function() {
    alert('Done flushing!');
  });
});

For convenience, it is also possible to not specify a transaction or callback, in that case a new transaction will be started automatically. For instance:

persistence.flush();
// or, with callback
persistence.flush(function() {
  alert('Done flushing');
});

Note that when no callback is defined, the flushing still happens asynchronously.

Important: Changes and new objects will not be persisted until you explicitly call flush(). The exception to this rule is using the list(...) method on a database QueryCollection, which also flushes first, although this behavior may change in the future.