Browse DevX
Sign up for e-mail newsletters from DevX


An Intro to Java Object Persistence with JDO : Page 3

The 'impedance mismatch' between relational databases' tabular orientation and object-oriented Java's hierarchical one is a perennial problem for which the Java world has several good solution offerings. The third in a three-part series, this article examines the ways that JDO attempts to simplify the chore of connecting relational databases and the Java programming language.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

The JDOUserDAO Implementation Class
The JDO reference implementation comes with a file-based data storage mechanism called fostore. The JDOUserDAO implementation class uses the fostore persistence-manager factory. It stores data in two files named fostore.btd and fostore.btx.

Author's Note: JDO supports a concept known as persistence-by-reachability. Persistence-by-reachability causes any transient instance of a class to become persistent when committed if the instance is reachable by a persistent instance.

Listing 3 illustrates the JDOUserDAO implementation class.

The JDO Bytecode Enhancer
A class must be enhanced before its instances can be managed by a JDO persistence engine. A JDO bytecode enhancer adds data and methods to classes to enable their instances to be managed by a persistence engine. A bytecode enhancer reads a class file and enhances it, outputting a class file with the necessary persistence functionality.

The JDO reference-implementation's bytecode enhancer modifies persistence-capable classes to run in the JDO environment. It accomplishes this by making changes to the class's bytecode. This enables the state of an instance of the class to be synchronized with data in a datastore.

Here is an example of running the JDO reference-implementation's bytecode enhancer for the sample application:

java -classpath $JDOHOME/jdo.jar:$JDOHOME/jdori.jar:$JDOHOME/jdori-enhancer.jar:
com.sun.jdori.enhancer.Main -d ../enhanced -s . -f ./com/jeffhanson/businesstier/model/package.jdo

The JDO Query Language
JDO defines a query language known as JDOQL. This language is embodied within the javax.jdo.Query interface. The JDO PersistenceManager defines methods for constructing instances of Query-instance implementation classes, as follows:
  • Query newQuery();
  • Query newQuery(Class cls);
  • Query newQuery(Class cls, Collection coll);
  • Query newQuery(Class cls, String filter);
  • Query newQuery(Class cls, Collection c, String filter);
  • Query newQuery(Extent ext);
  • Query newQuery(Extent ext, String filter);
A query filter is specified as a boolean expression that loosely resembles the boolean operators of SQL. The result for a query depends on whether or not the boolean expression evaluates to true for the specified candidate classes. The following method is provided by the Query interface for specifying a filter:
  • void setFilter(String filter);
Candidate classes can be specified using one of the following methods of the Query interface:
  • void setClass(Class candidateClass);
  • void setCandidates(Collection candidates);
  • void setCandidates(Extent candidates);
The Query interface provides methods to execute a query. Query parameters can be passed directly to any of these methods:
  • Object execute(Object param);
  • Object execute(Object param1, Object param2);
  • Object execute(Object param1, Object param2, Object param3);
  • Object executeWithMap(Map paramMap);
  • Object executeWithArray(Object[] paramArray);
The Query interface also provides a method for declaring an arbitrary group of comma-separated parameters:
  • void declareParameters(String paramStr);
This group of parameters must be formatted as a string defining Java-type and parameter-name pairs. For example, the following snippet illustrates a parameter group for a user's name and a user's account number:

query.declareParameters("String userName, int accountNumber");

The following illustrates a complete query using JDOQL:

String filter = "userInfo.fullName == fullName && " + "userInfo.zip.startsWith(userZip)"; Extent extent = persistenceMgr.getExtent(UserInfo.class, true); Query query = persistenceMgr.newQuery(extent, filter); query.declareParameters("String city, String state"); Collection result = (Collection)query.execute("Shire", "New York"); Iterator iter = result.iterator(); while(iter.hasNext()) { UserInfo user = (UserInfo)iter.next(); System.out.println("User: " + user.getID()); } query.close(result);

The structural differences between Java object hierarchies and relational database tables makes the challenge of persisting Java object data to and from relational databases quite intimidating for developers. The "impedance mismatch" between relational tables and Java object hierarchies has led to the development of several different object-persistence technologies attempting to bring together the relational world and the object-oriented world. JDO defines an object/relational framework and query language that ease the challenge of storage and retrieval of Java objects to and from a datastore.

Jeff Hanson has more than 18 years of experience in the software industry. He has worked as senior engineer for the Windows OpenDoc port and as lead architect for the Route 66 framework at Novell. He is currently Chief Architect for eReinsure, which specializes in providing frameworks and platforms for J2EE-based reinsurance systems. Jeff has also authored numerous articles and books.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date