| Sign In/My Account | View Cart |
Flawed JDO Points the Way to the "Objectbase"
Pages: 1, 2
Inserting a Person object into the objectbase is now a simple matter of using a properly-formatted SQL INSERT statement and the same JDBC code that you would typically use to insert an entry into a relational database. In Example 2, the program starts out by creating a new instance of a Person object by using the
new operator. Next, it sets the attribute values, using
the appropriate setXXX() methods. The program proceeds by
creating a prepared statement based upon a SQL INSERT
statement that has one argument in its VALUES clause.
Next, the program calls the prepared statement's
setObject() method, passing it the Person
object. The JDBC driver uses the information the program added to the
typemap to map the Person object to the
PERSON_TYPE UDT. Then, the program executes the prepared
statement using the executeUpdate() method, which returns
the number of rows inserted. It then performs the necessary cleanup by
closing the prepared statement and committing the transaction. At this
point, a new PERSON_TYPE object exists in the
PERSON_OBJECT_TABLE.
Example 2. A JDBC object-relational demonstration program
import java.io.*;
import java.math.*;
import java.sql.*;
import java.text.*;
import oracle.jdbc.driver.*;
/**
A program to demonstrate Oracle object-relational technology
*/
public class DemonstrateOR {
Connection conn;
public DemonstrateOR() {
try {
DriverManager.registerDriver(
new oracle.jdbc.driver.OracleDriver());
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@dssw2k01:1521:orcl",
"scott",
"tiger");
conn.setAutoCommit(false);
}
catch (SQLException e) {
System.err.println(e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
public static void main(String[] args)
throws Exception {
new DemonstrateOR().process();
}
public void process() throws SQLException {
PreparedStatement pstmt = null;
ResultSet rslt = null;
Statement stmt = null;
Person person = null;
// Update the connection's type map
try {
java.util.Map map conn.getTypeMap();
map.put("SCOTT.PERSON_TYPE",
Class.forName("Person"));
conn.setTypeMap(map);
}
catch (ClassNotFoundException e) {
System.err.println("Class Not Found Error: " + e.getMessage());
System.exit(1);
}
catch (SQLException e) {
System.err.println("SQL Error: " + e.getMessage());
System.exit(1);
}
// 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");
pstmt = conn.prepareStatement(
"insert into PERSON_OBJECT_TABLE values ( ? )");
pstmt.setObject(1, person);
int rows = pstmt.executeUpdate();
pstmt.close();
pstmt = null;
System.out.println(rows + " row inserted");
conn.commit();
}
catch (SQLException e) {
System.err.println("SQL Error: " + e.getMessage());
System.exit(1);
}
finally {
if (pstmt !=null)
try { pstmt.close(); } catch (SQLException ignore) { }
}
// Update the object using standard JDBC
Ref personRef = null;
try {
stmt = conn.createStatement();
rslt = stmt.executeQuery(
"select ref(p), " +
" value(p) " +
"from PERSON_OBJECT_TABLE p " +
"where name = 'Bales, Donald J.'");
rslt.next();
personRef = (Ref) rslt.getObject(1);
person = (Person)rslt.getObject(2);
rslt.close();
rslt = null;
stmt.close();
stmt = null;
// Let's change my email address
person.setEmail("don@donaldbales.com");
pstmt = conn.prepareStatement(
"update PERSON_OBJECT_TABLE p " +
"set value(p)=? " +
"where ref(p)=?");
pstmt.setObject(1, person);
pstmt.setRef(2, personRef);
int rows = pstmt.executeUpdate();
pstmt.close();
pstmt = null;
System.out.println(rows + " row updated");
conn.commit();
}
catch (SQLException e) {
System.err.println("SQL Error: " + e.getMessage());
System.exit(1);
}
finally {
if (rslt !=null)
try { rslt.close(); } catch (SQLException ignore) { }
if (stmt !=null)
try { stmt.close(); } catch (SQLException ignore) { }
if (pstmt !=null)
try { pstmt.close(); } catch (SQLException ignore) { }
}
try {
// Create and execute the object sql statement
stmt = conn.createStatement();
rslt = stmt.executeQuery(
"select value(p) from PERSON_OBJECT_TABLE p");
while (rslt.next()) {
// Cast the object
person = (Person)rslt.getObject(1);
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());
}
rslt.close();
rslt = null;
stmt.close();
stmt = null;
}
catch (SQLException e) {
System.err.println("SQL Error: " + e.getMessage());
System.exit(1);
}
finally {
if (rslt !=null)
try { rslt.close(); } catch (SQLException ignore) { }
if (stmt !=null)
try { stmt.close(); } catch (SQLException ignore) { }
}
// Delete the person
try {
stmt = conn.createStatement();
int rows = stmt.executeUpdate(
"delete PERSON_OBJECT_TABLE " +
"where ssn = '999-99-9999'");
stmt.close();
stmt = null;
System.out.println(rows + " row deleted");
conn.commit();
}
catch (SQLException e) {
System.err.println("SQL Error: " + e.getMessage());
System.exit(1);
}
finally {
if (stmt != null)
try { stmt.close(); } catch (SQLException ignore) { }
}
}
protected void finalize()
throws Throwable {
if (conn != null)
try { conn.close(); } catch (SQLException ignore) { }
super.finalize();
}
}
The next step in the demonstration is to update the
Person object the program just stored in the objectbase.
To do this, it retrieves the object's reference and an instance of the
object. To accomplish this, it utilizes the objectbase's functions
ref() and value() in the SQL
SELECT statement. I could have just used unique
information about the object's attributes to update it (the reference
is not necessary), but I wanted to show that a reference is similar in
concept to one in Java, in that it is a unique identifier for an
object.
First, the program creates a Statement object.
Next, it retrieves a ResultSet object by executing the SQL
SELECT statement. It forwards to the first row of the
result set by calling the next() method. Then, it stores
the REF object in a Ref variable by calling
getObject() and casting the returned Object
to a Ref. Next, it performs a similar call for the
Person object. Now that the program has a copy of the
Person object, I change my email address and proceed to
save it to the objectbase. To do so, the program starts out by
creating a properly-formatted SQL UPDATE statement that
once again utilizes the value() and ref()
objectbase functions. Next, it calls the prepared statement's
setObject() method twice; the first time to set the Person
object, and the second time to set its reference. Then, the program
tidies things up by closing the prepared statement and committing the
transaction. Now the objectbase contains an updated entry with my new
email address.
Retrieving an object is straightforward. If you were paying close
attention, you'll have realized that the program just did it when it updated
the Person object. This time, the program retrieves the
Person object and then echoes its attributes to the
screen. Proof that the program actually works. Wow.
Finally, the demonstration program executes a basic SQL
DELETE statement, using JDBC, to delete the
Person object from the objectbase. By doing so, the
program cleans up after itself, so you can try the program over and over
again to your heart's content.
As you have just seen in the demonstration program, using
object-relational
technology with JDBC is fairly simple and uncomplicated.
The real beauty behind Oracle's implementation of OR technology is that
you can have your cake and eat it too. You can use Oracle8i or
Oracle9i as an objectbase and then use the SQL TABLE
operator to create relational views for your non-object-oriented
development or third-party software tools. Or you can put an object
face on a legacy relational database by creating object views, so you
can access it with your OOD tools. This means that you don't have to
wait for a new project to start leveraging OR technology; you can start
using it immediately on any Oracle8i or Oracle9i server.
As you can see from Example 2, using JDBC with an object-relational technology is far simpler than using JDO. You can continue to leverage the strengths of SQL and at the same time migrate an existing relational database to an objectbase. Yet, the most important point of using OR technology is that the object model exists in the objectbase, not just in a set of Java programs. This means that the object model can be leveraged by any object-oriented programming language or OR-capable tool. With Oracle, it also means that you can continue to use your favorite relational tools as well.
Because I've provided a somewhat apples-to-apples comparison of JDBC and JDO, the example program does not completely demonstrate the capabilities of JDBC with OR technology. For example, it does not show the use of arrays (or collections, as they are also called) or methods. I do, however, cover these topics in-depth in my book Java Programming with Oracle JDBC. I urge you to bypass the extraneous layers of abstraction that JDO and similar object/relational mapping tools create, and address the fundamental problem: you need to use an objectbase for your object-oriented software solutions. I look forward to your feedback.
Donald Bales is a Systems Architect, Computer Applications Consultant, and Business Analyst specializing in the analysis, design, and programming of web-based, client-server, and distributed applications, the internationalization of existing applications, systems integration, and data warehousing.
Return to ONJava.com.
Showing messages 1 through 19 of 19.
The Java community needs to pick a production standard
MySQL
JDBC 2.0 Driver list
JDBC 2.0 Driver list
Apples to Apples?
Yes, Apples to Apples?
Apples to Apples?
Portability?
JDO can give us more than just JavaBean functionality
JDO can give us more than just JavaBean functionality
An ORDBMS is not just another persistence store for JDO
JDO can give us more than just JavaBean functionality
Otherwise, Microsoft with their unified model are going to have field day winning the server battle against a divided field.
Microsoft has picked it's database access methodology and is backing it with all of it's resources. It's got flaws, like all standards, but it has the advantage that everyone is using it.
When it comes to Java you don't know which one is going to win, and from a business technology adoption perspective that looks like a risk that doesn't need to be taken.
Does that mean that experimentation needs to stop? No, but we need to start talking about what is good for _production_ and differentiating that from what is cool, but not ready for prime time. I'm not saying what is, or is not, ready for prime time. I'm just saying that somebody big, needs to come out and back a Java database horse.
If you want a historical perspective, look what DOS did to UNIX about 12 years ago. UNIX had a chance on the Desktop, but because the vendors wouldn't adopt standards they were defeated by the unified, supported DOS camp. Now we talk about UNIX on the desktop as some sort of pipe-dream fantasy.
Java cannot afford a loss of that kind. If it is to survive long run it needs to make a solid showing in the server market. The way Apache is holding well against IIS.
Microsoft can be held at bay, but the Java community needs to unify and adopt proven reliable production standards to make that happen.