2.3. Inventory Maintenance

2.3.1. Persisting Objects
2.3.2. Deleting Objects

The most important element of a successful pet store product, say the experts, is an inventory maintenance mechanism. So, let's work on the Animal and Dog classes a bit to permit user interaction with the database.

This chapter should familiarize you with some of the basics of the JDO spec and the mechanics of compiling and enhancing persistence-capable objects. You will also become familiar with the mapping tool for propagating the JDO schema into the database.

First, let's add some code to AnimalMaintenance.java that allows us to examine the animals currently in the database.

  1. Add code to AnimalMaintenance.java.

    Modify the getAnimals method of AnimalMaintenance.java to look like this:

        /**
         *  Return a collection of animals that match the specified query filter.
         *
         *  @param  filter      the JDO filter to apply to the query
         *  @param  cls         the class of animal to query on
         *  @param  pm          the PersistenceManager to obtain the query from
         */
        public static Collection getAnimals (String filter, Class cls, 
            PersistenceManager pm)
        {
            // Get a query for the specified class and filter.
            Query query = pm.newQuery (cls, filter);
    
            // Add a single variable of type 'Animal' to this query to allow
            // for some reasonably powerful queries. This will be uncommented
            // in Chapter V.
            // query.declareVariables ("Animal animal;");
    
            // Execute the query.
            return (Collection) query.execute ();
        }
    
  2. Compile AnimalMaintenance.java.

    javac AnimalMaintenance.java
    
  3. Take a look at the animals in the database.

    java tutorial.AnimalMaintenance list Animal
    

    Notice that list optionally takes a query filter. Let's explore the database some more, this time using filters:

    java tutorial.AnimalMaintenance list Animal "name == 'Binney'"
    java tutorial.AnimalMaintenance list Animal "price <= 50"
    

    The JDO query language is designed to look and behave much like boolean expressions in Java. The name and price fields identified in the above queries map to the member fields of those names in tutorial.Animal. More details on JDO query syntax is available in Chapter 11, Query of the JDO Overview. For a definitive reference, consult the JDO specification.

Great! Now that we can see the contents of the database, let's add some code that lets us add and remove animals.

2.3.1. Persisting Objects

As new dogs are born or acquired, the store owner will need to add new records to the inventory database. In this section, we'll write the code to handle additions through the tutorial.AnimalMaintenance class.

This section will familiarize you with the mechanism for storing persistence-capable objects in a JDO persistence manager. We will create a new dog, obtain a Transaction from a PersistenceManager, and, within the transaction, make the new dog object persistent.

tutorial.AnimalMaintenance provides a reflection-based facility for creating any type of animal, provided that the animal has a two-argument constructor whose first argument corresponds to the name of the animal to add and whose second argument is an implementation-specific primitive. This reflection-based system is in place to keep this tutorial short and remove repetitive creation mechanisms. It is not a required part of the JDO specification.

  1. Add the following code to AnimalMaintenance.java.

    Modify the persistObject method of AnimalMaintenance.java to look like this:

        /**
         *  Performs the actual JDO work of putting <code>object</code>
         *  into the data store.
         *
         *  @param  object  the object to persist in the data store
         */
        public static void persistObject (Object object)
        {
            // Get a PersistenceManagerFactory and PersistenceManager.
            PersistenceManagerFactory pmf =
                KodoHelper.getPersistenceManagerFactory ("kodo.properties");
            PersistenceManager pm = pmf.getPersistenceManager ();
    
            // Obtain a transaction and mark the beginning
            // of the unit of work boundary.
            Transaction transaction = pm.currentTransaction ();
            transaction.begin ();
    
            pm.makePersistent (object);
    
            // Mark the end of the unit of work boundary,
            // and record all inserts in the database.
            transaction.commit ();
    
            System.out.println ("Added " + object);
    
            // Close the PersistenceManager and PersistenceManagerFactory.
            pm.close ();
            pmf.close ();
        }
    
    [Note]Note

    In the above code, we used the kodo.runtime.KodoHelper class. This class is similar to javax.jdo.JDOHelper, except that it provides some convenience methods for obtaining a PersistenceManagerFactory from properties enumerated in a resource at a given location, or in a specific JNDI location. This code could be implemented in a fully standards-based manner by loading the resource named kodo.properties into a Properties object and then passing this object to JDOHelper.getPersistenceManagerFactory.

    Also note that equivalent convenience methods are being considered by the JDO expert group for inclusion in the JDO 2 standard.

  2. Recompile AnimalMaintenance.java.

    javac AnimalMaintenance.java
    

You now have a mechanism for adding new dogs to the database. Go ahead and add some by running java tutorial.AnimalMaintenance add Dog <name> <price> For example:

java tutorial.AnimalMaintenance add Dog Fluffy 35

You can view the contents of the database with:

java tutorial.AnimalMaintenance list Dog

2.3.2. Deleting Objects

What if someone decides to buy one of the dogs? The store owner will need to remove that animal from the database, since it is no longer in the inventory.

This section demonstrates how to remove data from the data store.

  1. Add the following code to AnimalMaintenance.java .

    Modify the deleteObjects method of AnimalMaintenance.java to look like this:

        /**
         *  Performs the actual JDO work of removing 
         *  <code>objects</code> from the data store.
         *
         *  @param  objects     the objects to persist in the data store
         *  @param  pm          the PersistenceManager to delete with
         */
        public static void deleteObjects (Collection objects, PersistenceManager pm)
        {
            // Obtain a transaction and mark the beginning of the
            // unit of work boundary.
            Transaction transaction = pm.currentTransaction ();
            transaction.begin ();
    
            for (Iterator iter = objects.iterator (); iter.hasNext (); )
                System.out.println ("Removed animal: " + iter.next ());
    
            // This method removes the objects in 'objects' from the data store. 
            pm.deletePersistentAll (objects);
    
            // Mark the end of the unit of work boundary, and record all
            // deletes in the database.
            transaction.commit ();
        }
    
  2. Recompile AnimalMaintenance.java.

    javac AnimalMaintenance.java
    
  3. Remove some animals from the database.

    java tutorial.AnimalMaintenance remove Animal <query>
    

    Where <query> is a query string like those used for listing animals above.

All right. We now have a basic pet shop inventory management system. From this base, we will add some of the more advanced features suggested by our industry experts.