JDO : Metadata API

When using JDO you need to define which classes are persistent, and also how they are persisted. JDO has allowed XML metadata since its first revision, and introduced support for annotations in JDO 2.1. JDO 3.0 introduces a programmatic API to do the same task.

Defining Metadata for classes

The basic idea behind the Metadata API is that the developer obtains a metadata object from the PersistenceManagerFactory, and adds the definition to that as required, before registering it for use in the persistence process.

PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(propsFile);
...
JDOMetadata md = pmf.newMetadata();

So we have a JDOMetadata object and want to define the persistence for our class mydomain.MyClass, so we do as follows

PackageMetadata pmd = md.newPackageMetadata("mydomain");
ClassMetadata cmd = pmd.newClassMetadata("MyClass");

So we follow the same structure of the JDO XML Metadata file adding packages to the top level, and classes to the respective package. Note that we could have achieved this by a simple typesafe invocation

ClassMetadata cmd = md.newClassMetadata(MyClass.class);

So now we have the class defined, we need to set its key information

cmd.setTable("CLIENT").setDetachable(true).setIdentityType(IdentityType.DATASTORE);
cmd.setPersistenceModifier(ClassPersistenceModifier.PERSISTENCE_CAPABLE);

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);

And we define also define fields/properties via the API in a similar way

FieldMetadata fmd = cmd.newFieldMetadata("name");
fmd.setNullValue(NullValue.DEFAULT).setColumn("client_name");
fmd.setIndexed(true).setUnique(true);

Note that, just like with XML metadata, we don't need to add information for all fields since they have their own default persistence settings based on the type of the field.

All that remains is to register the metadata with the persistence process

pmf.registerMetadata(md);

Accessing Metadata for classes

Maybe you have a class with its persistence defined in XML or annotations and you want to check its persistence information at runtime. With the JDO Metadata API you can do that

TypeMetadata compmd = pmf.getMetadata("mydomain.MyOtherClass");

and we can now inspect the information, casting the compmd to either javax.jdo.metadata.ClassMetadata or javax.jdo.metadata.InterfaceMetadata.

Please note that you cannot currently change metadata retrieved in this way, only view it