http://www.developer.com/

Back to article

Accessing Data Through Persistence Frameworks


May 18, 2004

About the Frameworks Series

Besides the Java language, a world of Java frameworks exists. These frameworks can afford substantial improvements in programmer productivity and enhance the quality, performance, reliability, and interoperability of different Java applications. Fortunately, many of these popular and widely used frameworks are open source projects, so anyone can benefit from them if he can invest some time learning when and how to use such frameworks. This article is the second installment in the frameworks series and aims to introduce persistence frameworks in general and the open source Java persistence framework, Castor JDO, in particular.

To read previously published article in this series, follow this link: Frameworks.

Introduction

Most enterprise applications need access to a relational database. The Java standard for accessing relational databases is the JDBC APIs that utilize SQL as a data manipulation language. This approach of directly accessing a relational database from an object-oriented Java application was shown to be inefficient and introduces a problem called "object-relational impedance mismatch," or simply "impedance mismatch" for short.

Impedance mismatch refers to the differences between object-oriented technology and relational technology. Object technology relies on objects that have data and behavior. Relational technology supports the storing of data in tables and handling these data via a Data Manipulation Language (DML) such as SQL. Furthermore, objects have identity and are traversed using direct access, whereas RDBS tables have a primary key and are related via values in foreign and primary keys. Finally, RDBMS has no equivalent to Java's object inheritance for data and behavior.

An approach for solving the impedance mismatch problem is to introduce an abstract layer, called a persistence layer, between the relational database and the object model of the application, as in Figure 1. This layer fully encapsulates the database access from your business objects. Thus, instead of writing code to handle your database, you are required only to define meta-data that represents how your relational database will be mapped into objects and deal directly with these objects.

Persistence Frameworks

Figure 1: Persistence Frameworks adds an abstraction layer between the OO application model and the relational database

Sun's Java Data Objects (JDO)

The Java Community Process (JCP) developed the standard JDO as a high-level API specification and a reference implementation. JDO transparently handles the mapping of Java objects to relational databases.

Sun didn't distribute a free JDO implementation, but it released a reference implementation. This reference implementation is a way for Sun to prove that the specification is available. Instead of using a relational database, the reference implementation writes the persistent objects to the file system. Of course, there exist commercial implementations that are compatible with Sun's JDO specifications. Some of these products are listed in Table 1.

Table 1: Commercial JDO Tools
Vendor JDO product
Hemisphere Technologies JDO Genie
LIBeLIS LiDO
MVCSoft JDO Toolkit
Object Frontier FrontierSuite
Object Industries JRelay
Prism Technologies OpenFusion JDO
Poet Software Fast Objects
Signsoft IntelliBO
SolarMetric Kodo JDO

Open Source Persistence Frameworks

In addition to the JDO commercial products, a number of free and robust persistence frameworks exist. These frameworks have the same target as Sun's JDO although they are not compatible with the JDO standards. Three of the most popular persistence frameworks in the open source community are Hibernate, Castor, and OJB.

Castor JDO

The Castor JDO is an open source persistence framework developed under the auspices of exolab.org. As with Sun's JDO, Castor JDO aims to transparently persist Java objects. However, you should remember that Castor JDO is not an implementation of Sun's JDO.

Working with Castor JDO could be briefly described in the following four steps:

  1. Write a configuration file.
  2. Write mapping file(s).
  3. Implement persistent objects.
  4. Issue queries using Castor's Object Query Language (OQL).

Database Configuration File

To access a database, you first need to establish a connection to it. Castor maintains information required to access a database (e.g. name, engine) in a configuration file named "database.xml".

This configuration file specifies the means to obtain a connection to the database server, the mapping between Java classes and tables in that database server, and the service provider to use for talking to that server.

A typical example of a database configuration file is shown in Listing 1.

<database name="shippingDB" engine="postgresql">
   <driver class-name="org.postgresql.Driver"
           url="jdbc:postgresql:shippingDB">
      <param name="user" value="Administrator"/>
      <param name="password" value=""/>
   </driver>
   <mapping href="mapping.xml" />
</database>

Listing 1: database.xml configuration file

The database to connect to is specified by the name attribute and the database engine is specified by the engine attribute. The <driver> element specifies the JDBC driver for this database engine and the URL path to the shippingDB.

The <param> elements have user and password information that the driver needs to log in to the database. Finally, the mapping file and its location are specified by using the <mapping> element and the href attribute.

Mapping File

The core task of using any persistence framework is specifying how to map an object to a database table. Some persistence frameworks, such as JRelational, allow the developer to hard code the mapping information in the implementation of the persistent class. Other frameworks, like Castor JDO, allow the developer to specify mapping information in (a) separate file(s) called (a) mapping file(s). By following the second approach, developers can change the object-relational mapping without the need to recompile their Java code.

The Castor JDO uses an XML-based file to specify the mapping information. The following is a high-level example of a mapping file.

<mapping>
   <class>
      <map-to />
      <field>
         <sql />
      </field>
      ...
   </class>
</mapping>

Listing 2: Castor JDO Mapping File

Each persistent class is represented by a <class> element and the corresponding database table is specified by the <map-to> element. Each <field> element represents a member in the persistent class and the <sql> element represents the field in the database table to which the <field> element maps.

Mapping Difficulties

Mapping a Java class to a relational database table is not always straightforward. A Java class may exhibit the following relationships between objects:

  1. one-to-one
  2. one-to-many
  3. many-to-many
  4. class dependent on another
  5. class related to another
  6. class derived from another

This is where Castor JDO comes in handy. Castor JDO facilitates the creation of complex persistent Java objects (for example, objects with collection members or composite objects) allowing persistent objects to mirror the complex structure of the underlying relational database (as in tables with foreign keys).

Interested readers are encouraged to browse the related links at the end of this article for a group of tutorials that help you get started with Castor JDO and practice how to map a real-world database model.

Implementing Persistent Classes

Castor's Java objects look similar to JavaBeans components. Therefore, a persistent object contains a pair of (getter/setter) methods for each member variable that will be mapped to a field in the database table. More code may be added when the persistent object exhibits a to-many relationship. Listing 3 is an example of a Castor persistent object.

public class Product
{
   private int       _id;
   private String    _name;
   private float     _price;

   public int getId()
   ...

   public void setId( int anId )
   ...
  // more methods ...
}

Listing 3: Persistent object example

Object Query Language

Now, instead of directly accessing database tables, you will work with persistent objects. SQL is a data manipulation language suitable for querying relational databases. SQL is not suitable for querying persistent objects, so most persistence frameworks provide their own object query language. Like other persistence frameworks, Castor JDO uses its own object query language (OQL) for querying persistent objects. OQL is much simpler and relieves the developer for the complexity of SQL.

Conclusion

Persistence frameworks are promising tools to persist your data. They relieve you from your own buggy persistence layers and complicated JDBC and SQL code. In addition to commercially available JDO products, a number of robust and widely-used open source persistence frameworks exist. In this article, you learned the basic fundamental steps to follow when building a persistence layer using Castor JDO. Basically, these steps are similar in other persistence frameworks.

Acknowledgements

The author would like to thank Rosemarie Graham for suggesting the idea of this series and Developer.com for publishing the series.

About the Author

Yasser EL-Manzalawy has been a Java programmer and instructor since 1998. He is currently an assistant lecturer at the Systems & Computers Engineering Department, AZHAR University, Cairo. His Ph.D. research project aims to extend the Java language for agent-based systems.

Related Links

The Castor Project homepage provides the latest release of Castor JDO and there you can browse a wealth of articles and documentation materials.

Sitemap | Contact Us

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