Newsletters Subscriptions Forums Media Kit About Us Contact Search Home

Stuff
OS/400 Edition
Volume 2, Number 24 -- December 4, 2003

Persist Java Objects on DB2 for iSeries with JDO


by Marc Logemann

[The code for this article is available for download.]

One of the most discussed Java standards is Java Data Objects, or JDO. Many people see this standard as a competitor of entity beans, from the Java 2 Enterprise Edition (J2EE) world. You can persist data to a database with both, but with JDO you can also persist data in a client/server desktop environment, without running an application server. Because of the stability and robustness of DB2 for iSeries, JDO will be a perfect partner when working with database applications.

JDO: The Big Picture

With JDO, you generally solve the problem of mapping relational data to Java objects (in other words, you solve the problem of persisting data). In most Java projects, you see individually created persistence or mapping frameworks, which cover only a few aspects of persistence and are usually very limited. With JDO--or better, with the products implementing JDO as a standard--you get complete transparent persistence. This means, your objects or JavaBeans don't know anything about the ability to be persisted. You write them without thinking of persistence; you can concentrate completely on the business behaviour. Nearly all vendors use byte code manipulation of classes that should be persisted after compiling them. This way, you are shielded from the implementation details of the persistence framework. But how does JDO know how to persist an object? Everything important will be stored in XML files, which the byte code enhancer uses for inserting the implementation code.

The rules for persisting objects are stored in XML, and because JDO is a standard, you might think that you can change vendors without changing the XML definitions. Unfortunately, this is only half of the truth. The most important elements in an XML file are the mappings from an object attribute to fields in a database table. These mappings are not standardized yet and are vendor-specific. This will be addressed in the JDO 2.0 specification, which is in a very early stage. So keep in mind that even though JDO is a standard, you won't have the ability to change the vendor very quickly.

IntelliBO and the Configuration Step

I will use Signsoft's IntelliBO JDO implementation to demonstrate how JDO works. As I mentioned, you can use a different vendor, but then you will have different XML elements and different tag naming inside the XML. When you want to try the examples for yourself, I recommend downloading the IntelliBO trial version.

Before I get into the code details, we have to set up IntelliBO to work with DB2 for iSeries. Because configuring IntelliBO is not the main topic, I recommend downloading db-config.xml and copying it to the lib folder of the IntelliBO installation. You should back up the existing one beforehand. Then, after copying, just edit the file and change the lines, with the following keys, to suit your needs:

  • The url is the IP address or valid DNS name of your iSeries. Note that after the last slash (/), you should define your default library, also called schema, so the JDBC driver knows where the tables are located. You can find more information on that in the JTOpen documentation, which is part of the JTOpen package.

  • The user is a valid user with enough rights to access the tables we will create later.

  • The password is that of the valid user.

Then copy the jt400.jar file, which is part of the JTOpen package, to the lib folder of your IntelliBO installation (otherwise the specified driver in db-config.xml can't be found).

The First JDO Example

Say you wanted to persist a customer object to a customer database table. With JDO, you can start writing the customer class (Customer.java) without any thoughts about persistence. It looks very normal, right? But how do you tell the JDO framework what to do with that object during runtime? Signsoft (and I assume every other vendor on the market) provides visual tools for doing the mapping of the class to the database. This visual tool is a front-end for creating the resulting XML. Of course, you can also start some editor and code the XML for yourself.

Assume further that you have the following database table for storing the customer:

CUSTPF
__________________________________________
custno			int
custname		varchar(100)

In most projects, you will see homegrown persistence classes mostly resulting in helper classes, which manually map the fields of a JDBC resultSet to the attributes of the business classes. This kind of code is not easy to maintain and requires more SQL knowledge than with JDO. So to map the example, you have to define an xml file, which is needed during enhancement and runtime.

The class tag defines the name of the persistence-capable class and how the identity will be managed. In this example, I have chosen the datastore identity, which means you don't have to worry about the primary key in the customer class--all you need is an additional field in the table, which will be managed by the JDO implementation. So before proceeding, let's add the following column to the CUSTPF table:

IBOXFID 		int

This is the default column name when using datastore identity with IntelliBO. But how does the JDO engine know what key is next? Another default implementation is the use of a sequence table, which holds the next usable key; we also have to create this table to go ahead:

TSEQUENCE
__________________________________________
FKEY			int
FNAME		varchar(100)

You can override these settings by defining them in the XML, but as long you only define "use datastore identity," you will have to live with the default.

Back to the XML file. Everything between the field tag defines how an attribute maps to the database. In the example, you see that the attribute custName directly maps to the table column custname, and the attribute custNumber to the column custno. In the example, we won't use custno as PrimaryKey, as many people would do, but will instead use a non-business primary key, like IBOXFID. Of course, you could use custNumber as PrimaryKey, but this would complicate our first contact with JDO a little bit.

The very last thing to explain in the XML is the extension tag with the key table-name. This only defines that our Customer class maps to a table called CUSTPF; if we did not define this, IntelliBO would use a default prefix rule to name the table, but in most cases the tables are already there and you really don't want to rename them. One word on the tag extension. You see this tag over and over in our mapping XML file. The tag is part of the JDO spec, but the actual behavior of it is defined in the key attribute. The different values in the key attribute are not defined, so you have to see this extension tag as a specification "backdoor" for implementing non-portable features. This is still a major drawback in the 1.0 spec of JDO, which makes it not very trivial to change vendors, because vendor B will most likely use different extension keys than vendor A. The expert group who is on the way to defining JDO 2.0 these days will tackle this issue.

But let's get to the end of the first example. Now we have created a customer class and the required JDO XML file (customer.jdo). Let's first compile the class inside your IDE, or in command-line style with javac; the resulting class file will be enhanced in the next step. The enhancer is shipped with the JDO implementation; in our case it's in the bin folder of the IntelliBO installation and is called enhancer.exe. If you are developing on a Unix-style operating system, there is an enhancer.sh file also in the folder. Once you run the enhancer application, the resulting class file is persistence-capable. The enhancer injected the necessary code to do persistence the JDO way. All this can also be done inside IntelliBO's IDE, where you can visually define the XML content and also do the enhancement.

Now we are nearly finished. CustomerMaintenance.java is the class performing the application logic. There is also one more class, Utils.java, which performs some low-level work like getting a JDO PersistenceManager. You should look at the Utils.getPersistenceManager() method inside this class to see what it's doing, but I won't cover it here. Before compiling these two classes, be sure you have all JAR files from the IntelliBO lib folder in your classpath, as well as the lib folder itself.

More interesting than the compilation is what is going on in the run() method of CustomerMaintenance. After getting the PersistenceManager and a Transaction from it, you create a Customer object, as you would do anyway. You then call some setter methods and call makePersistent(CustomerObject). The most important line of code is the one that calls the commit method, commit(), on the Transaction object. After this, all the work starts behind the scenes. All objects that received the signal from the method makePersistant() will be written to the database. That's it!

Don't Forget the Basics

Are you missing something? Perhaps lines like this:

try . . .
Connection c = . . . //get some connection from some pool or whatever
Statement statement = c.createStatement();
String sql = "insert into custpf values(. . .,. . .)
statement.execute(sql);
catch . . . .
finally . . . .

This is only a small excerpt of the JDBC API you would normally code, when not using JDO; if you want more performance, you would use PreparedStatement of the JDBC API, which would clutter your code even more. All these checked exceptions, the tedious ResultSet looping--you name it--all are gone and are not necessary anymore with JDO. And best of all, the resulting SQL of the JDO engine will most likely be better than the SQL of the average developer.

Let's Query It

After inserting objects, it's time to retrieve them. See the code after the commit() method. You retrieve a Query object invoking newQuery() on the PersistenceManager; as a parameter you provide the class where you want to get the objects from. After calling execute() on the query object, you get a collection returned as Object. The rest is common Java programming, iterating over a collection and calling getter methods on our customers.

Do I Need It?

When programming Java, you certainly need a persistence mechanism, because in an object-oriented world you have the object-relational mismatch. Another reason for using professional persistence mechanisms is that developers are shielded from the JDBC/SQL API, which can be cumbersome. There are many persistence products out there. Some are proprietary, while others rely on standards like JDO. Give JDO a try and see the pros and cons for yourself; it's an easy starting point for trying out persistence, and I bet you will stick with it.


Marc Logemann is founder of Logentis, a German consulting company that focuses on iSeries and Java services and development. Marc is involved in Java- and PHP-based open-source projects and likes reading books about new technologies. E-mail: midrangeserver@logentis.de


Sponsored By
ASNA

Why we chose ASNA Visual RPG for .NET:

"WebSphere isn't the easiest software to install and work with. The big difference is that applications can be developed in AVR for .NET so much faster than with WebSphere and Java. [AVR for .NET] allows for the use of familiar legacy RPG language constructs and the use of the powerful .NET Framework at the same time. This allows our RPG/400 developers to be effective in the .NET environment quickly. Whether a customer wants a new application to be developed or an existing AS/400 application to be re-written, we firmly believe that AVR for .NET is the development platform of choice."
-Brian Bunney, PBSI

Learn more about AVR for .NET today!
http://www.asna.com/infoavrdotnet.aspx



Editors: Shannon O'Donnell, Kevin Vandever
Managing Editor: Shannon Pastore
Contributing Editors: Howard Arner, Raymond Everhart,
G. Wayne Hawks, Joe Hertvik, Ted Holt, Marc Logemann, David Morris
Publisher and Advertising Director: Jenny Thomas
Advertising Sales Representative: Kim Reed
Contact the Editors: To contact anyone on the IT Jungle Team
Go to our contacts page and send us a message.


THIS ISSUE
SPONSORED BY:

LANSA
ASNA
Damon Technologies
Profound Logic Software


BACK ISSUES

TABLE OF
CONTENTS
Customizing Your Development with Extensible RPG

Persist Java Objects on DB2 for iSeries with JDO

Back to Basics: Get That Code Out of Your RPG

OS/400 Alert: Microsoft Exposes IE to Hackers



Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.