Document version 0.91.
The Petshop example uses Tapestry and JPOX This document is a guide for building the Petshop example from source. It also discusses the recommended design choices followed by the example code, and it compares the use of JPOX to the use of the Data-Access-Object (DAO) design pattern. JPOX provides a downloadable sample with the code described here. While this sample is for JPOX, it can be converted to DataNucleus easily.
This example, called Petshop, is a port of the Petshop example (Version 0.41) created and distributed by Luis Neves. Like the VLib example that is also distributed with DataNucleus, the Petshop example shows how a Tapestry Web application can use JDO.
The original Petshop example is, I believe, a recreation of the J2EE Petstore example. The fictitious business case for the Petshop is an on-line business that sells pets. The Petshop Web application allows people to browse or search the catalog of pets, select pets for purchase, and complete the order. Luis Neves shows off Tapestry’s support for internationalization by supporting both a Portuguese and English version of the site. This port continues to do the same.
The original Petshop example uses JDBC and the Data Access Object (DAO) pattern to access the database and provide the persistence layer. The ported example uses JDO to provide the persistence layer.
Developers who are familiar with or learning Tapestry will benefit from this example. Developers who are very familiar with the DAO pattern using JDBC and who are thinking of adopting JDO will benefit from comparing this version of the example with the original.
Technical managers who are evaluating whether to use JDO in their development process will benefit from considering the metrics drawn from this example. (See last section.)
Tapestry is a Web application framework from Apache. It can be found at http://jakarta.apache.org/tapestry.
Tapestry abstracts from the multi-threadedness of the Servlet API and provides tight coupling between the HTTP request and response handling code. The same components that participate in the rendering of page also accept the user’s response to the page. The handshaking between HTTP responses and the Java code is handled by the framework, so that most dynamic information presented on the page and most user input to the page are represented as properties of the Tapestry page or its components. The user’s next request action results in an invocation of a listener method on the page or one of its components. Every Tapestry page and component is single-threaded by design, and contrary to what you might be inclined to believe, it performs quite well because of object pooling.
The Petshop example is a port (or fork) of the Petshop example that is distributed by Luis Neves.
Unlike the original which uses the DAO pattern and JDBC to implement the model, the Petshop example distributed by DataNucleus uses JDO.
In general, most of the presentation files are unchanged, and those that are changed, are changed very little. The controller code varies class-by-class from no change, to one or two little changes, to many small changes. The model code has been extensively modified, although there is a family resemblance to the original code.
This example is distributed as source only. This section documents the steps you need to follow to successfully build the example from source.
For many of you, the preliminary configuration steps for a development environment are no-ops, since you will have several of these pieces already installed and ready to use. For the rest of you, this checklist will help you pick up the pieces that you need.
Before running the build file you must configure it for your development environment. To do this, assign the correct values for your development environment to the properties defined near the top of the build file. Here is a short description of each property found there.
The two main build targets are clean and deploy . Invoke Ant in the customary way. The Ant download provides ample documentation for getting started with Ant.
Invoke first the clean task, then the deploy task. In both cases, you should see a message that indicates that the build was successful.
After the task deploys the Petshop Web application, start up the Web server if it is not already running. Visit the site by using an URL like the following, http://localhost:8080/petshop/app . The host name and port may differ for your development environment. If everything has gone well, you’ll see a web page like the following.
The site is easy to use. It has a link to the help page that tells you more. The password for the “j2ee” user is “j2ee”.
The original Petshop example comes with data definition language (DDL) scripts to initialize a McKoi database, a Microsoft SQL Server database, or a PostgreSQL database. DataNucleus itself supports a large number of relational databases.
When building applications that use JDO, real world requirements often include the need to support an existing database schema. For that reason, I adopted the requirement that the port of Petshop to DataNucleus would support the existing McKoi data schema. This requirement led to three results. One, the port does support the same McKoi data schema as the original Petshop example. No changes whatsoever to the existing tables. DataNucleus does add its own DataNucleus_TABLE, which it uses to keep track of the persistent classes. Two, in order to get the mapping functionality that I needed to meet this requirement, I had to adopt the DataNucleus 1.1 line which has already implemented some of the mapping functionality found in the coming JDO 2.0 specification. Three, to minimize the amount of testing, I limited myself to only the McKoi database schema.
If someone wants to support either Microsoft SQL Server or PostgreSQL using the original DDL (shipped with this example), the changes required, which may not be many, should be limited to the JDO metadata. If someone wants to lift the restriction that an existing schema must be supported, again the metadata must change, and in addition, a means must be devised to initialize the test data for the schema that DataNucleus will automatically generate.
Most of the features of JDO that the Petshop example uses are required features in every JDO 1.0 compatible implementation. In one case, the Petshop example uses a JDO optional feature, nontransactional-read, which is implemented by DataNucleus and nearly every JDO implementation.
The coming JDO 2.0 standard will likely include better support for specifying the object-to-relational mapping in the JDO metadata. The DataNucleus 1.1.x line of releases is currently a preview version for the coming JDO 2.0 standard as expressed in the early release draft. For the moment, the JDO metadata for the Petshop is definitely tied to the DataNucleus 1.1.x line, but it is anticipated that this metadata will become standard JDO 2.0 metadata with little change. As it stands now, the Petshop metadata file does not use any extension tags, which are the tags that allow the use of vendor specific features in the metadata.
The Petshop example also uses the expected JDO 2.0 support for the toLowerCase method in JDOQL (JDO’s query language).
In short, the VLib example as written will work only with DataNucleus 1.1.x. It will evolve, as the JDO 2.0 standard and as work on DataNucleus 1.1.x continues, to become dependent only on JDO 2.0.
In the tutorial for the VLib example, another example of a Tapestry Web application that uses DataNucleus, I identified several design choices and described why I thought they were good choices. Did I follow those recommendations in this example? The following checklist provides the rundown.
My primary motivation in doing this port was to demonstrate the advantages of using JDO when compared directly to coding the DAO pattern with the use of JDBC.
The Data Access Object (DAO) design pattern provides an adapter between plain, old, Java objects (POJOs) and various databases that can be accessed using JDBC. In essence, the DAO pattern requires that you write the persistence layer for your data classes, and it gives you guidance on how to go about it. By writing DAO code, you expend business resources to create the infrastructure for your application. Expending development resources on coding the DAO pattern is common and not inconsequential.
The following table shows the impact on the Petshop example of switching from the code that implements the DAO pattern with JDBC to the code that uses JDO. Table 1-1 compares original DAO version of Petshop to the new JDO version of Petshop based on two metrics. The SLOC metric is the count of the source lines of code. This count does not include blank lines or comment lines. The CC metric is the count of classes, including interfaces. The Petshop application is broken down into two sections, the model and the controller. Since the view is HTML templates and XML files, it is not included in the analysis of Java code. The view was nearly unchanged by the port.
Table 1-1: Metrics comparing the use of DAO to JDO
As the table shows, the port had no impact on the controller code by these metrics. On the other hand, the impact on the model is dramatic. The amount of model code is reduced by over forty percent. Less code written means less time creating it, less time debugging it, less time testing it, and less time maintaining it. Overall, the amount of Java code for the entire application is reduced by approximately twenty-five percent. Most managers will find it hard to ignore numbers like these.
If you believe as I do, that it is easier to learn to use JDO than to learn to code the DAO pattern with JDBC, and if you believe, as I do, that using a JDO implementation will lead to a more robust and a better performing persistence layer than having your best developers create it from scratch, then the reduction in code coupled with these advantages creates a compelling argument for using JDO in your next development project.