1.3 Establish a Datastore Connection and Transaction

Now that our classes have been enhanced, their instances can be stored in a datastore. We now examine how an application establishes a connection with a datastore and executes operations within a transaction. We begin to write software that makes direct use of the JDO interfaces. All JDO interfaces used by an application are defined in the javax.jdo package.

JDO has an interface called PersistenceManager that has a connection with a datastore. A PersistenceManager has an associated instance of the JDO Transaction interface used to control the start and completion of a transaction. The Transaction instance is acquired by calling currentTransaction( ) on the PersistenceManager instance.

1.3.1 Acquiring a PersistenceManager

A PersistenceManagerFactory is used to configure and acquire a PersistenceManager. Methods in the PersistenceManagerFactory are used to set properties that control the behavior of the PersistenceManager instances acquired from the factory. Therefore, the first step performed by a JDO application is the acquisition of a PersistenceManagerFactory instance. To get this instance, call the following static method of the JDOHelper class:

static PersistenceManagerFactory getPersistenceManagerFactory(Properties props);

The Properties instance can be populated programmatically or by loading property values from a property file. Example 1-6 lists the contents of the property file we will use in our Media Mania application. The PersistenceManagerFactoryClass property on line [1] specifies which JDO implementation we are using by providing the name of the implementation's class that implements the PersistenceManagerFactory interface. In this case, we specify the class defined in Sun's JDO reference implementation. Other properties listed in Example 1-6 include the connection URL used to connect to a particular datastore and a username and password, which may be necessary to establish a connection to the datastore

Example 1-6. Contents of jdo.properties
javax.jdo.PersistenceManagerFactoryClass=com.sun.jdori.fostore.FOStorePMF     [1]

The format of the connection URL depends on the particular datastore being accessed. The JDO reference implementation has its own storage facility called File Object Store (FOStore). The ConnectionURL property in Example 1-6 specifies that the datastore is located in the database directory, which is located in our project's root directory. In this case, we have provided a relative path; it is also possible to provide an absolute path to the datastore. The URL specifies that the FOStore datastore files will have a name prefix of fostoredb.

If you are using a different implementation, you will need to provide different values for these properties. You may also need to provide values for additional properties. Check with your implementation's documentation to determine the properties that are necessary.

1.3.2 Creating a FOStore Datastore

To use FOStore we must first create a datastore. The program in Example 1-7 creates a datastore using the jdo.properties file; all applications use this property file. Line [1] loads the properties from jdo.properties into a Properties instance. The program adds the com.sun.jdori.option.ConnectionCreate property on line [2] to indicate that the datastore should be created. Setting it to true instructs the implementation to create the datastore. We then call getPersistenceManagerFactory( ) on line [3] to acquire the PersistenceManagerFactory. Line [4] creates a PersistenceManager.

To complete the creation of the datastore, we must also begin and commit a transaction. The PersistenceManager method currentTransaction( ) is called on line [5] to access the Transaction instance associated with the PersistenceManager. The Transaction methods begin( ) and commit( ) are called on lines [6] and [7] to start and commit a transaction. When you execute this application, a FOStore datastore is created in the database directory. Two files are created: fostore.btd and fostore.btx.

Example 1-7. Creating a FOStore datastore
package com.mediamania;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;

public class CreateDatabase {
    public static void main(String[] args) {
        create(  );
    public static void create(  ) {
        try {
            InputStream propertyStream = new FileInputStream("jdo.properties");
            Properties jdoproperties = new Properties(  );
            jdoproperties.load(propertyStream);     [1]
            jdoproperties.put("com.sun.jdori.option.ConnectionCreate", "true");     [2]
            PersistenceManagerFactory pmf =
                        JDOHelper.getPersistenceManagerFactory(jdoproperties);     [3]
            PersistenceManager pm = pmf.getPersistenceManager(  );     [4]
            Transaction tx = pm.currentTransaction(  );     [5]
            tx.begin(  );     [6]
            tx.commit(  );     [7]          
        } catch (Exception e) {
            System.err.println("Exception creating the database");
            e.printStackTrace(  );

The JDO reference implementation provides this programmatic means to create a database. Most databases provide a utility separate from JDO for creating a database. JDO does not define a standard, vendor-independent interface for creating a database. Creation of a datastore is always datastore-specific. This program illustrates how it is done using the FOStore datastore.

In addition, when you are using JDO with a relational database, there is often an additional step of creating or mapping to an existing relational schema. The procedure to follow for establishing a schema that corresponds with your JDO object model is implementation-specific. You should examine the documentation of the implementation you are using to determine the necessary steps.