Persist data with Java Data Objects, Part 2

Sun JDO vs. Castor JDO

1 2 Page 2
Page 2 of 2

Mapping

The mapping module reads and parses the XML-based mapping file, and then provides information to Castor JDO for automatic translation between database data and Java objects.

Loading a mapping file is simple:

mapping = new Mapping(this.getClass().getClassLoader());
mapping.loadMapping("mapping.xml");

Queries

Castor JDO OQL is a subset of OQL, but not compatible with Sun JDO OQL. Like the Sun JDO OQL, Castor JDO OQL resembles SQL, except that it performs operations directly on Java objects instead of database tables, making the language more appropriate for use within a Java-based application.

The public interface org.exolab.castor.jdo.Query is also simple:

      public void bind( Object value )
      public QueryResults execute()

Note: The Query interface actually contains many bind(...) methods overloaded to allow for different argument types to be bound. Please consult Castor JDO documentation for details.

Below, you will find some JDO OQL query examples:

 OQLQuery query = db.getOQLQuery("SELECT p FROM Person p WHERE name LIKE  AND dob >  AND married="); 
OQLQuery query2 = db.getOQLQuery("select a from com.foo.Login a where to_lower(loginname) like  order by lastname, firstname"); 
OQLQuery query3 = db.getOQLQuery( "SELECT c FROM Course c WHERE categories =  AND program =  AND status = " );

More advanced query features are still under development -- consult the documentation for more information.

Data-store support

Castor JDO supports many relational databases. The list includes the usual suspects, such as Oracle and SQL Server, but also open source data stores, such as MySQL, InterBase, and SAP DB. Castor JDO only supports relational databases.

Castor JDO: The good, the bad, and the ugly

Castor JDO compares to the ideal persistence layer quite favorably. It is elegant in its simplicity, nonintrusiveness, and transparency -- although its transparency is limited to relational data stores. The API is concise and well thought out.

As an open source project, Castor JDO is free and modifiable. But along with open source benefits come its drawbacks: limited support and lack of tutorials, or nonskeletal documentation for that matter. Lack of support and documentation can add hours to your first Castor project. Open or not, single implementation and limited support is not a good combination. You might stumble upon an issue currently not handled by Castor, grinding your project to a halt. With multiple implementations, you could look at alternative JDO products. This issue, though, is not Castor-specific; it is common with all open source software.

However, from a purely technical viewpoint, Castor is well thought out and developer friendly. It will remain popular with developers for a long time.

JDO vs. JDBC

Let's now compare JDO with JDBC (Java Database Connectivity). Look at some sample code written using Castor JDO running in a J2EE environment (the session bean method sets transaction boundaries). The following code creates a new Incident instance, adds three children objects of class EventLogItem, and stores the object and its children in a database:

  // Add a new Incident
try {
  Incident i = new Incident(title);
  i.addEventLogItem(new EventLogItem(username, comment));
  i.addEventLogItem(new EventLogItem(username, comment2));
  i.addEventLogItem(new EventLogItem(username, comment3));
  // pm is an instance of the PersistenceEngine
  Long id = (Long) pm.create(i);
  return id.longValue();
}
catch (Exception ex) {
   // Handle exception
}

The same logic implemented with JDBC would look as follows:

 // Create Incident
try {
  Connection conn = ds.getConnection();
   PreparedStatement ps1 = conn.prepareStatement("select 
MAX(incidentID) from incidents");
   ResultSet rs = ps1.executeQuery();
    if (rs.next()) {
         incidentID = rs.getInt(1);
         incidentID++;
    }
    PreparedStatement ps2 = conn.prepareStatement(createIncidentSQL);
    ps2.setLong(1, incidentID);
    ps2.setString(2, title);
    int rows = ps2.executeUpdate();
    
    Incident incident = new Incident(title);
    incident.setIncidentID(incidentID);
    PreparedStatement ps3 = conn.prepareStatement("select MAX(itemID) from " + LOG_TABLE);
    for (int i = 0; i < 3; i++) {
        int itemID = 0;
        ResultSet rs3 = ps3.executeQuery();
        if (rs3.next())
               itemID = rs3.getInt(1) + 10;
        PreparedStatement ps4 = conn.prepareStatement(createLogSQL);
        ps4.setLong(1, itemID);
        ps4.setLong(2,incidentID);
        ps4.setLong(3, System.currentTimeMillis());
        ps4.setString(4, username);
        ps4.setString(5, comment);
        ps4.setInt(6, 0);
        ps4.setInt(7, 0);
       int logrows = ps4.executeUpdate();
       EventLogItem eli = new EventLogitem(username, content);
       incident.addEventLogitem(eli);
      }
    conn.close();}
        catch (Exception e) {
       // Handle connection
    }

JDO's one clear advantage: less code to write and maintain. In most nontrivial cases, I found that the JDBC API produces an average of three times more code than the JDO API.

JDO vs. entity beans

Many in the developer community debate, rather heatedly, the advantages of JDO over those of entity beans. If a developer wants to take advantage of EJB's (Enterprise JavaBeans) lifecycle management, security, and an entity bean's distributed nature, then EJB is the right choice. However, both the Sun and Castor JDO specifications have much less overhead and provide more design freedom -- data objects are still Java objects, not entity beans. In most cases, developers don't need entity bean's remote capability because they access the entity beans through appropriate session beans. That approach follows the Façade pattern, which you can use with JDO; using JDO to model data and session beans as the interface feels natural.

JDO in real life

Every technology has its strengths and weaknesses. Contrary to widespread expectations, JDO in the real world doesn't necessarily free architects from knowing their data store.

Developers must also devote considerable effort to keeping the data model, the mapping file, and the database model in synch. You must consider that issue for major projects with changing requirements -- requirements change in probably 99 percent of software projects. Luckily, the available Java code and/or DDL (data description language) generators are growing more mature. Also, you will find that using alternative approaches to persistence in synching up data models proves more painful -- JDBC comes to mind.

To use JDO-based products, you must master JDO-specific approaches to data-type and relationship mapping, caching mechanisms, and many other powerful features. Persistence is a complex subject, and the product documentation does not necessarily tell you the whole story. However, once you've completed the learning phase, your development productivity will shoot through the roof with JDO.

Software architects working on large, scalable environments should note that JDO does not currently support distributed caching. Developers have two obvious options available:

  • Implement caching, but not clustering
  • Implement clustering, but not caching

Help is on the way, however. Several vendors, like ObjectFrontier and GemStone have announced distributed cache products, and some will work with JDO.

JDO: The way to go

Regardless of which solution you decide on, JDO is an exciting, new, and almost mission-critical-ready technology. The main advantage of JDO over entity beans is its relative simplicity; it lets developers concentrate more on business logic. Less code to write means fewer errors, which means higher software development productivity. Just as Java's automatic memory management frees developers from mundane and completely unnecessary pointer arithmetic details, JDO relieves developers from labor-intensive persistence issues.

More JDO-compliant products are appearing on the market. JDO makes it easier to write data-oriented applications, and the advantage is especially pronounced in the J2EE development area.

Both the Sun and Castor JDO approaches come closer than any other alternative to the ideal persistence layer presented in Part 1. No other technology available offers a comparable combination of portability, power, and simplicity. What's not to like?

Jacek Kruszelnicki is president of Numatica Corporation, an information technology consulting firm providing expertise in information-systems strategy development, analysis, and planning; software development; and training. Jacek (pronounced Yatsek) received his master's degree in computer science from Northeastern University in Boston, Mass., and has more than 15 years' experience delivering maintainable, large-scale, distributed enterprise solutions.

Learn more about this topic

1 2 Page 2
Page 2 of 2