JDO 2.3 Metadata API

Defining how classes are to be persisted has always been a subjective part of any persistence process. Some people like XML, some like annotations, and some want it all to be done magically with a sprinkle of stardust. JDO has always allowed configuration using XML. In JDO 2.1 we introduced the ability to use annotations (and a mix of annotations and XML). With JDO 2.3 we’re introducing a third way … via an API. Let’s assume we have a class we want to persist

public class Client
{
String name;

}

The basic idea is as follows. We want to define the metadata programmatically for our class
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(propsFile);

JDOMetadata md = pmf.newMetadata();

So our PMF has created a new metadata object to work with. This corresponds to the top level of a metadata file. We can now add packages and classes as required to define the persistence. So something like this …
PackageMetadata pmd = md.newPackageMetadata(“org.datanucleus”);

so we have a package for our class. Now let’s define the persistence of the class :-
ClassMetadata cmd = pmd.newClassMetadata(“Client”);
cmd.setTable(“CLIENT”).setDetachable(true);
cmd.setIdentityType(IdentityType.DATASTORE);
cmd.setPersistenceModifier(ClassPersistenceModifier.PERSISTENCE_CAPABLE);

and the class needs persistence for the field “name” defining (since we don’t want to accept default persistence specifications) :-
FieldMetadata fmd = cmd.newFieldMetadata(“name”);
fmd.setNullValue(NullValue.DEFAULT).setColumn(“client_name”);
fmd.setIndexed(true).setUnique(true);

and of course we can define everything else as required, so to persist it into its own table, and to have versioning, etc :-
InheritanceMetadata inhmd = cmd.newInheritanceMetadata();
inhmd.setStrategy(InheritanceStrategy.NEW_TABLE);
DiscriminatorMetadata dmd = inhmd.newDiscriminatorMetadata();
dmd.setColumn(“disc”).setValue(“Client”);
dmd.setStrategy(DiscriminatorStrategy.VALUE_MAP).setIndexed(Indexed.TRUE);

VersionMetadata vermd = cmd.newVersionMetadata();
vermd.setStrategy(VersionStrategy.VERSION_NUMBER);
vermd.setColumn(“version”).setIndexed(Indexed.TRUE);

All that remains to do is enable this metadata in our persistence process
pmf.registerMetadata(md);

Key points :

  • you get your starting object (JDOMetadata) from the PMF.
  • you only need to add fields and attributes that are non-defaulted. As with a metadata file, all fields of standard types are by default persistent
  • you can chain mutator operations. I’ve split them above for readability, but they could have been on a single line.
  • once populated you register the start object with the PMF. Thereafter when that class is used in persistence it will use that metadata definition.
  • If a class is already known to the PMF (has its file-based metadata registered) then you can’t redefine it using this API.

The logical next step is to be able to view the metadata defined in XML or annotations. You can do this as follows
ComponentMetadata compmd = pmf.getMetadata(“mydomain.MyClass”);

and you can now interrogate the metadata of this class (cast it to ClassMetadata or InterfaceMetadata). Please note that it is not supported being able to change metadata that is already registered, just view it.

Final point worth making is that the DataNucleus implementation of these metadata classes will output the (approximate) XML text representation when you call “toString()” on the metadata object, so for example the metadata generation above results in

so you also have an easy way of converting your API generated metadata into XML should you wish to transfer it to a file for later use.

This is now in DataNucleus SVN trunk. You need the latest Apache JDO API jar (also in DataNucleus SVN, and in the nightly build repositories).

Advertisements
This entry was posted in DataNucleus, JDO, JPA, Persistence. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s