Welcome to JDOCurrent

Developed with

The Basic

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:
how would your application layers "know" what is the "current" PersistenceManager to use in the "current" interaction ?
In fact, each call to ApplicationStorage.getPersistenceManager(); creates a new PersistenceManager.
One possible solution is to add a PersistenceManager argument to each method requiring it.
The key is: requiring it.
You must know which method requires the PersistenceManager in advance. Feasible but not very clean.

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.

The JDOCurrent Approach

Another different approach would be the possibility to really access the "current" PersistenceManager to use in the "current" interaction.
Here it comes JDOCurrent. A JDOCurrent instance provides the "current" PersistenceManager valid for the "current" "context", whatever a context is.
Your ApplicationStorage class becomes:
    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 !!
But, with JDOCurrent, two calls to ApplicationStorage.getPersistenceManager() return always the same PersistenceManager as long as the "context" is the same.

The Interaction Context

What is an interaction context ?
From JDOCurrent point of view, is anything that remains constant for the duration of some processing.
In practical, there are two type of context:
  • thread based
  • transaction based

    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.
    As long as a thread is alive the corresponding PersistenceManager is valid.
    (Unless you invoke a specific API to detach the PersistenceManager from the current context).

    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.
    Currently, JDOCurrent natively supports JPOX, JPOX 1.2 and DataNucleus, so there is no need to configure anything: just drop the jar in the classpath and use it.

    Links

    Download JDOCurrent source distribution
    Download JDOCurrent binary distribution

    For any comment, question and suggestion contact voodoo(at)objectmagic.org (Yes, even for bug report)