Pages

GAE/J and DataNucleus v3 - Part 2

Saturday, November 5, 2011
In the previous post we saw some initial changes to make GAE/J DataNucleus plugin work with the latest version of DataNucleus plugins. In this post we describe some further features of interest to GAE users that they weren't able to use before.

Storage Version
With v2 of the plugin it will, by default, persist using a new "storage version". In v1 of the plugin it persisted no explicit information about relations, and instead relied on doing queries for parent key to find related objects; obviously when all relations were owned then this was valid. In v2 of the plugin it persists a property in the Entity for each relation (containing the Key(s) of the related object(s)), at the owner side always. In the case of unowned relations (see below) it also will persist a property in the Entity at the non-owner side of a bidirectional relation. Obviously all existing data uses v1 of the storage version, but don't let that concern you since the plugin will check for presence of this property, and if not present then fall back to v1 behaviour to get the related objects. As entities are updated the data will be migrated to v2 storage version (a migration tool to do the job in one pass is in the works also).


Unowned Relations
By default in GAE/J all relations are owned meaning that any child objects have the parent object Key as part of their Key, and persisted as part of the same entity-group. This is obviously useful in optimising retrieval of data, but there are times when you simply want your model persisting and not have imposition of ownership. In v2 of the plugin you can have unowned relations, where each object is in its own entity-group. To define a relation like this, see the following example
@PersistenceCapable
public class A
{
    @Persistent(primaryKey="true", valueStrategy=IdGeneratorStrategy.IDENTITY) 
    long id;

    @Unowned
    B b;

    ...
}

@PersistenceCapable
public class B
{
    @Persistent(primaryKey="true", valueStrategy=IdGeneratorStrategy.IDENTITY) 
    long id;

    @Unowned
    @Persistent(mappedBy="b")
    A a;

    String name;

    ...
}

So when we persist an object of type A with related B it will do the following
  1. PUT the A, generating its Key, but without property for B
  2. PUT the B, generating its Key, and with a property referring to the key of A
  3. PUT the A with the property referring to the key of B.
It should be noted that the @Unowned annotation is simply a shortcut for @Extension(vendorName="datanucleus", key="gae.unowned", value="true")

Be aware that if you persist unowned relations in a transaction then you will need to have multi-entity-group transactions enabled, since each object is in its own entity group.


Datastore Identity
With JDO the user has the choice of having their own primary key field (application-identity), or having the identity of the object defined for them (datastore-identity). GAE v1 only allowed application-identity. In v2 of the GAE DN plugin it also allows datastore-identity. To give an example

@PersistenceCapable
@DatastoreIdentity(strategy=IdGeneratorStrategy.IDENTITY)
public class MyClass
{
    ...
}

So with this class it will persist an Entity and its Key will use IDENTITY strategy.


Interface Fields
With v2 of the plugin you can now have fields of interface type (representing a persistable type) and persist them as you would normally do. Refer to the DataNucleus docs for how to do it (paying particular attention to the type of the field in metadata)


That's a brief summary of some of the more noteworthy improvements, and hopefully now GAE/J using JDO (or JPA) is a much more pleasant place to be, and you can refer almost directly to the DataNucleus docs for many more features now. In addition to the above changes, and in fixing various other minor bugs, the code structure has been changed quite a bit so future enhancements ought to be much more rapidly achievable

No comments:

Post a Comment