Using JDO is simple.
Managing JDO objects is simple: you create a PersistenceManagerFactory at some application initialization point
and use it to get PersistenceManager when it's time to access your persistent objects.
Normally, applications use a single PersistenceManagerFactory and the most obvious way of accessing
it is to define some class with a static member (or a singleton) holding the reference.
public class ApplicationStorage {
protected static PersistenceManagerFactory persistenceManagerFactory;
public static PersistenceManagerFactory getPersistenceManagerFactory() {
return persistenceManagerFactory;
}
public static setPersistenceManagerFactory(PersistenceManagerFactory pmf) {
persistenceManagerFactory = pmf;
}
public static PersistenceManager getPersistenceManager() {
return persistenceManagerFactory.getPersistenceManager();
}
}
Then, when you need a PersistenceManager:
PersistenceManager pm = ApplicationStorage.getPersistenceManager();
// use the PM
The above approach works quite well in many situations, but there is a subtle issue:
Here a different approach: provide the PersistenceManager to some constructor of the relevant classes.
This is cleaner because the knowledge of the PersistenceManager requirement is necessary only at setup time.
Anyway, the drawback is that you need to create new instances of the relevant classes at each interaction.
public class ApplicationStorage {
protected static PersistenceManagerFactory persistenceManagerFactory;
protected static JDOCurrent jdoCurrent;
public static PersistenceManagerFactory getPersistenceManagerFactory() {
return persistenceManagerFactory;
}
public static setPersistenceManagerFactory(PersistenceManagerFactory pmf) {
persistenceManagerFactory = pmf;
jdoCurrent = JDOCurrent.getJDOCurrent(persistenceManagerFactory);
}
public static PersistenceManager getPersistenceManager() {
return jdoCurrent.getPersistenceManager();
}
}
Then, when you need a PersistenceManager:
PersistenceManager pm = ApplicationStorage.getPersistenceManager();
// use the PM
Your code is not changed !!
In a thread-based interaction-style, an application has one (long-lived) PersistenceManager bound
to each thread in which persistence processing take place.
Calling
PersistenceManager pm = ApplicationStorage.getPersistenceManager();
from different threads gives different PersistenceManager.
A second interaction-style binds the PersistenceManager to the current JTA transaction.
This PersistenceManager lives as long as the JTA transaction is active.
As you might have noted, the application knows nothing the interaction-style in use to
access the current PersistenceManager.
In fact, everything is setup here
jdoCurrent = JDOCurrent.getJDOCurrent(persistenceManagerFactory);
JDOCurrent uses a "provider" approach to support the different interaction-styles,
it checks if the PersistenceManagerFactory is working in JTA-controlled environment, in which case
it uses the javax.transaction.TransactionManager to get the current transaction, otherwise it
uses a thread-local provider implementation.
Unfortunately, there is no standard way to obtain the TransactionManager in use from a PersistenceManagerFactory,
so proper provider factories are tailored to match different products.
For any comment, question and suggestion contact voodoo(at)objectmagic.org (Yes, even for bug report)