Flawed Understanding of JDO Leads to FUD

Flawed Understanding of JDO Leads to FUD

Example Application

I will now discuss my experiences of reviewing Bales' program and my development of an equivalent program with JDO. Bales' first step is to create a user-defined type (UDT) using a SQL CREATE TYPE command and then create an associated object table. It is not necessary to provide these underlying datastore data definitions using most JDO implementations. Many of the JDO implementations automatically generate these data definitions for the Java application. If there is an existing set of tables, implementations provide a means to define the mapping between your Java object model and the underlying database.



Next Bales introduces a Person class. It is necessary for his class to import other classes from java.io and java.sql. His class needs to implement the SQLData interface, using SQLInput and SQLOutput streams. In JDO, it is not necessary to import such types or implement the methods that marshal and demarshal the object. I used his program as the starting point for my implementation of the program in JDO. The definition of his data members included the following:

private String = name;

private String = address;

private String = ssn;

// etc.

Another problem I discovered was the following method definition:

public void setEmail(String Email) {

  this.email = email;

}

I discovered this when my email address seemed to always be set to null. The reason for this is that the name of the parameter (Email) is not being assigned to the field itself. These two pieces of code prevent his program from being compiled and tested successfully. The equivalent JDO application that I provide here has been compiled and tested.

The Persistent Class Person

The following class, Person, is the class to be stored in the database. This is the same class defined in Bales' article, with the above corrections made and also removing code not necessary when using JDO.

package onjava;

public class Person {

  private String name;

  private String address;

  private String ssn;

  private String email;

  private String home_phone;

  private String work_phone;

 

  public Person() {

  }

  // Accessors

  public String getName() {

    return name;

  }

  public String getAddress() {

    return address;

  }

  public String getSsn() {

    return ssn;

  }

  public String getEmail() {

    return email;

  }

  public String getHomePhone() {

    return home_phone;

  }

  public String getWorkPhone() {

    return work_phone;

  }

  // Mutators

  public void setName(String name) {

    this.name  = name;

  }

  public void setAddress(String address) {

    this.address  = address;

  }

  public void setSsn(String ssn) {

    this.ssn  = ssn;

  }

  public void setEmail(String email) {

    this.email  = email;

  }

  public void setHomePhone(String homePhone) {

    home_phone  = homePhone;

  }

  public void setWorkPhone(String workPhone) {

    work_phone  = workPhone;

  }

}

Bales' Person class was 78 lines long. The class defined above has the same functionality in only 50 lines. The savings comes from the fact that with JDO I do not need to provide the methods readSQL, writeSQL, and getSQLTypeName. As Bales notes himself, this code is tedious. It could also be error-prone. With a JDO implementation, this same functionality is automatically generated for my class. So the same functionality is necessary, but with JDO this code is generated for the application, reduces the developer's workload, and avoids error-prone code.

The Enhancer and Metadata

Specifically, the code is added by an enhancer directly to my .class file. The enhancer is given the file Person.class and a JDO metadata file that lists the persistent classes and any other persistence-related information not expressible in Java. For this very simple schema, the metadata is trivial:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE jdo SYSTEM "jdo.dtd">

<jdo>

  <package name="onjava" >

    <class name="Person" />

  </package>

</jdo>

The enhancer adds the code necessary to provide transparent persistence of the class, including methods needed to migrate data between the object and the database. The JDO enhancement contract for performing this is designed in such a manner that the code placed in my class is portable and will work with any JDO implementation. The resulting .class file is vendor-neutral.

The Application

Below I provide the application program that performs the same operations as provided in the DemonstrateOR program written by Bales.

package onjava;

import javax.jdo.*;

import java.util.*;

import java.io.*;

/**

A program to demonstrate JDO

*/

public class DemonstrateJDO {

    PersistenceManager pm;

    Transaction tx;

 

public DemonstrateJDO() {

    PersistenceManagerFactory pmf = null;

    try {

        InputStream propStream =

                      new FileInputStream("jdo.properties");

        Properties props = new Properties();

        props.load(propStream);

        pmf = JDOHelper.getPersistenceManagerFactory(props);

    } catch(Exception ex){

        System.out.print("Error creating PMF");

        System.out.println(ex);

        System.exit(1);

    }

    pm = pmf.getPersistenceManager();

    tx = pm.currentTransaction();

}

 

public static void main(String[] args)

               throws Exception {

    new DemonstrateJDO().process();

}

 

public void process(){

    Person person = null;

    // Insert a person object

    try {

      // create a new instance

        person  = new Person();

        person.setName("Bales, Donald J.");

        person.setAddress("Downers Grove, IL 60516");

        person.setSsn("999-99-9999");

        person.setEmail("balesd@compuserve.com");

        person.setHomePhone("(999) 999-9999");

        person.setWorkPhone("(999) 999-9999");

        tx.begin();

        pm.makePersistent(person);

        tx.commit();

    }

    catch (JDOException e) {

      System.err.println("JDO Error: "+e.getMessage());

      System.exit(1);

    }

 

    // Update the object using standard JDO

    try {

        // Let's change my email address

        tx.begin();

        person.setEmail("don@donaldbales.com");

        tx.commit();

    }

    catch (JDOException e) {

        System.err.println("JDO Error: "+e.getMessage());

        System.exit(1);

    }

 

    try {

        // Print the Persons in the database

        tx.begin();

        Extent persons = pm.getExtent(Person.class,true);

        Iterator personIter = persons.iterator();

        while( personIter.hasNext() ){

            person = (Person) personIter.next();

            System.out.println("name:       " +

                    person.getName());

            System.out.println("address:    " +

                    person.getAddress());

            System.out.println("ssn:        " +

                    person.getSsn());

            System.out.println("email:      " +

                    person.getEmail());

            System.out.println("home phone: " +

                    person.getHomePhone());

            System.out.println("work_phone: " +

                    person.getWorkPhone());

        }

        persons.close(personIter);

        tx.commit();

    }

    catch (JDOException e) {

      System.err.println("JDO Error: "+e.getMessage());

      System.exit(1);

    }

 

    // Delete the person

    try {

        tx.begin();

        Extent persons = pm.getExtent(Person.class,true);

        Query query = pm.newQuery(persons,

                               "ssn == \"999-99-9999\"");

        Collection rslt = (Collection) query.execute();

        Iterator iter = rslt.iterator();

        person = (Person) iter.next();

        query.close(rslt);

        pm.deletePersistent(person);

        tx.commit();

    }

    catch (JDOException e) {

      System.err.println("JDO Error: "+e.getMessage());

      System.exit(1);

    }

  }

 

  protected void finalize()

   throws Throwable {

    if (pm != null)

      try { pm.close(); }catch (JDOException ignore){ }

    super.finalize();

  }

}

Once again, the JDO program is smaller. DemonstrateOR is 197 lines of code, my DemonstrateJDO program is 119 lines. Not only is the JDO program smaller, it also seems simpler to me. But deciding which program is simpler is likely a subjective opinion. You can decide for yourself which program is easier to understand.

Prev  [1] [2] [3] Next

Close    To Top
  • Prev Article-Java:
  • Next Article-Java:
  • Now: Tutorial for Web and Software Design > Java > JDOnJDBCnSQLJ > Java Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction