Clearly JDO is complex and there are many ways of utilising it in your application. This section
attempts to give a few pointers that you may find useful in avoiding issues. This guide should be
read in conjunction with the Performance Tuning Guide.
There should be 3 steps in your use of JDO.
- Deciding which classes to persist and how to persist them to the datastore
- Creating the schema or validating that it matches the persistence decisions taken in step 1
- Running your application
Many people like to perform steps 2 and 3 together because JPOX will support the creation of schemas
dynamically. This can, however, confuse issues where the MetaData is incompatible with the existing
schema for example, or where the MetaData definition is incorrectly specified. It is always best to use
JPOX SchemaTool to either create the schema (where you are creating a new schema) or to validate it (where
you are using an existing schema). This means that you isolate issues about the schema and MetaData before running
your application.
Once you have isolated all issues around the schema and the MetaData you can then run your application. Since
you know that the schema exists and is valid for your MetaData you can safely run with the properties
org.jpox.autoCreateSchema, org.jpox.autoCreateTables, org.jpox.autoCreateColumns,
org.jpox.autoCreateConstraints, org.jpox.validateTables, and org.jpox.validateConstraints
all set to false. This will lead to much better performance for your application since fewer checks will
be made at runtime of the schema structure.
Creation of PersistenceManagerFactory objects can be expensive and so is to be kept to a minimum.
Depending on the structure of your application, use a single PersistenceManagerFactory per datastore wherever possible.
Clearly if your application spans multiple servers then this may be impractical, but should be borne in mind.
Clearly the structure of your application will have a major influence on how you utilise a PersistenceManager.
A pattern that gives a clean definition of process is to use a different PersistenceManager for each request to the
data access layer. This reduces the risk of conflicts where one thread performs an operation and this impacts on
the successful completion of an operation being performed by another thread. Creation of PersistenceManager's is
not an expensive process.
When you need to use objects in a different layer of your application (outside of the datastore layer) you need
a mechanism for taking the objects in a form where they can be used. JDO2 provides detach/attach functionality
for this purpose. There are two ways of detaching objects. The first is to use PersistenceManager.detachCopy()
however this can be computationally expensive since it has to create copies of the objects (and also down an object
graph too if required). The second way is to use the PMF property javax.jdo.option.DetachAllOnCommit which means
that the existing objects that have been enlisted in the current transaction are automatically migrated into
detached state. This is not computationally expensive and means that you can now use your objects and update
them directly before sending them back to the datastore layer for persisting.
... (create PMF with javax.jdo.option.DetachAllOnCommit set to true)
// Datastore Tier - persist any new objects
PersistenceManager pm = pmf.getPersistenceManager();
Transaction tx = pm.currentTransaction();
try
{
tx.begin();
pm.makePersistent(myObj);
tx.commit();
// myObj is now detached
}
finally
{
if (tx.isActive())
{
tx.rollback();
}
}
// Business Tier - update your objects
... update "myObj" in your business layer
// Datastore Tier - persist any changes to your objects
PersistenceManager pm = pmf.getPersistenceManager();
Transaction tx = pm.currentTransaction();
try
{
tx.begin();
// Attach the updated (detached) myObj
pm.makePersistent(myObj);
tx.commit();
// myObj is now detached again for any further updates
}
finally
{
if (tx.isActive())
{
tx.rollback();
}
}
So the move to "detached" state is transparent and you can use your objects directly when they leave the
datastore tier.