public class ElementHolder { long id; private Set elements = new HashSet(); ... } public class Element { String name; ... } public class SubElement extends Element { double value; ... }
There are times when you need to replicate data between datastores. In many cases datastores themselves provide a means of doing this, however if you want to avoid using datastore-specific functionality you can utilise JDO to perform this task. JDO2 allows replication by use of detach/attach functionality. We demonstrate this with an example
public class ElementHolder { long id; private Set elements = new HashSet(); ... } public class Element { String name; ... } public class SubElement extends Element { double value; ... }
so we have a 1-N unidirectional (Set) relation, and we define the metadata like this
<jdo> <package name="org.apache.jdo.test"> <class name="ElementHolder" identity-type="application" detachable="true"> <inheritance strategy="new-table"/> <field name="id" primary-key="true"/> <field name="elements" persistence-modifier="persistent"> <collection element-type="Element"/> <join/> </field> </class> <class name="Element" identity-type="application" detachable="true"> <inheritance strategy="new-table"/> <field name="name" primary-key="true"/> </class> <class name="SubElement"> <inheritance strategy="new-table"/> <field name="value"/> </class> </package> </jdo>
and so in our application we create some objects in datastore1, like this
PersistenceManagerFactory pmf1 = JDOHelper.getPersistenceManagerFactory("jdo.1.properties"); PersistenceManager pm1 = pmf1.getPersistenceManager(); Transaction tx1 = pm1.currentTransaction(); Object holderId = null; try { tx1.begin(); ElementHolder holder = new ElementHolder(101); holder.addElement(new Element("First Element")); holder.addElement(new Element("Second Element")); holder.addElement(new SubElement("First Inherited Element")); holder.addElement(new SubElement("Second Inherited Element")); pm1.makePersistent(holder); tx1.commit(); holderId = JDOHelper.getObjectId(holder); } finally { if (tx1.isActive()) { tx1.rollback(); } pm1.close(); }
and now we want to replicate these objects into datastore2, so we detach them from datastore1 and attach them to datastore2, like this
// Detach the objects from "datastore1" ElementHolder detachedHolder = null; pm1 = pmf1.getPersistenceManager(); tx1 = pm1.currentTransaction(); try { pm1.getFetchPlan().setGroups(new String[] {FetchPlan.DEFAULT, FetchPlan.ALL}); pm1.getFetchPlan().setMaxFetchDepth(-1); tx1.begin(); ElementHolder holder = (ElementHolder) pm1.getObjectById(holderID); detachedHolder = (ElementHolder) pm1.detachCopy(holder); tx1.commit(); } finally { if (tx1.isActive()) { tx1.rollback(); } pm1.close(); } // Attach the objects to datastore2 PersistenceManagerFactory pmf2 = JDOHelper.getPersistenceManagerFactory("jdo.2.properties"); PersistenceManager pm2 = pmf2.getPersistenceManager(); Transaction tx2 = pm2.currentTransaction(); try { tx2.begin(); pm2.makePersistent(detachedHolder); tx2.commit(); } finally { if (tx2.isActive()) { tx2.rollback(); } pm2.close(); }
These objects are now replicated into datastore2. Clearly you can extend this basic idea and replicate large amounts of data.