Sunday, November 08, 2009

GAE data storage

GAE data storage is pretty basic. Relationships are especially weak (guess this is inherited from both Java (JDO and such) and XML as a data store). Sure it works for simple object persistence but for more or less serious stuff it won't cut it. Let's consider simplest of them all bi-directional one-to-many. Data integrity aside it ain't worth it because of inflexibility. For managed one-to-many (read storing everything in one XML file) there are just two ways of resolving relationship - either doing nothing (default) or prefetching all (by setting @Persistent(defaultFetchGroup = "true")). That inflexibility comes at a cost of fetching all children just to add another one since there is no way of adding a child with some sort of foreign key and thus parent.getChildren().add(child) is the only way to add a child. Unmanaged one-to-many solve "foreign key issue", but come at a cost of updating parent any time child is added. The bottom line is - relationships should never be part of a class or data storage. They need to be modeled "orthogonally" to both objects and data storage in "data model" similar to EOF. When it comes to GAE and Java in general this implies same old - same old - very basic objects (XML documents as storage) with no JDO relationships. Relationships need to be modeled and implemented as part of data logic (read all relationship management needs to be implemented in getters and setters) - stone age or yet another way Java is Cobol of XXI century. N.B. Encoded string PK defined as
@PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true") private String encodedKey; @Persistent @Extension(vendorName="datanucleus", key="gae.pk-name", value="true") private String pk;
are equivalent to Key and key generation using pk field as follows
@PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) Key id; ... this.id = KeyFactory.createKey(InAppPurchase.class.getSimpleName(), pk);

Followers