The Source for Java Technology Collaboration
User: Password:



Lance Andersen's Blog

February 2006 Archives


JDBC 4.0 Wrapper Interface

Posted by lancea on February 23, 2006 at 02:46 PM | Permalink | Comments (1)

The Wrapper interface provides a mechanism for JDBC users to be able to access an instance of a resource which has been wrapped for architectural reasons. This mechanism helps to eliminate the need to use non-standard means to access vendor specific resources.

The following JDBC interfaces are subinterfaces of the Wrapper interface:

  • java.sql.Connection
  • java.sql.DatabaseMetaData
  • java.sql.ParameterMetaData
  • java.sql.ResultSet
  • java.sql.ResultSetMetaData
  • java.sql.Statement
  • javax.sql.Datasource

The Wrapper interface consists of two methods:

  • isWrapperFor - Returns true if this either implements the interface argument or is directly or indirectly a wrapper for an object that does.
  • unwrap - Returns an object that implements the given interface to allow access to non-standard methods, or standard methods not exposed by the proxy.
Here is a simple example of using these new methods:

  Statement stmt = conn.createStatement();
  Class clzz = Class.forName("oracle.jdbc.OracleStatement");
  OracleStatement os;
  if(stmt.isWrapperFor(clzz)) {
     os = stmt.unwrap(clzz);
     os.defineColumnType(1, Types.NUMBER);
  }



JDBC 4.0 SQLException Enhancements

Posted by lancea on February 21, 2006 at 11:58 AM | Permalink | Comments (0)

The following enhancements were made in JDBC 4.0 in order to provide a better developer's experience when dealing with SQLExceptions:
  • Support for causal relationships
  • For-each loop support
  • New SQLException sub-classes

Causal Relationship Support

We have added support for the Java SE chained exception mechanism by adding additional constructors allowing for the cause to be specified. The cause could be a non-SQLException, it is just what resulted in the SQLException being thrown.

This feature does not reduce the need for the getSQLException() method as it is possible for multiple unique SQLExceptions to be generated (not all DBs do this currently but could going forward and is allowed by the SQL Standard) due to executing a statement on the backend.

Your code would look something like the following to process the causal relationships:

catch(SQLException ex) {
     while(ex != null) {
        System.out.println("SQLState:" + ex.getSQLState());
        System.out.println("Error Code:" + ex.getErrorCode());
        System.out.println("Message:" + ex.getMessage());
        Throwable t = ex.getCause();
        while(t != null) {
            System.out.println("Cause:" + t);
            t = t.getCause();
        }
        ex = ex.getNextException();
    }
}

For Each Loop Support

The SQLException class now implements the Iterable interface providing support for the For each loop feature added in J2SE 5.0. The navigation of the loop will walk through the SQLException and its cause (if any):


catch(SQLException ex) {
     for(Throwable e : ex ) {
        System.out.println("Error encountered: " + e);
     }
}

Categorization of SQLExceptions

JDBC 4.0 has introduced two categories of SQLException: SQLTransientException and SQLNonTransientException.

A SQLNonTransientException would be thrown in instances where a retry of the same operation would fail unless the cause of the SQLException is corrected. The following Exceptions have been added, each extending SQLNonTransientException:

  • SQLFeatureNotSupportedException
  • SQLNonTransientConnectionException
  • SQLDataException
  • SQLIntegrityConstraintViolationException
  • SQLInvalidAuthorizationException
  • SQLSyntaxErrorException

A SQLTransientException will be thrown in situations where a previously failed operation might be able to succeed when the operation is retried without any intervention by application-level functionality. The following Exceptions have been added, each extending SQLTransientException:

  • SQLTransientConnectionException
  • SQLTransactionRollbackException
  • SQLTimeoutException

Please refer to the JDBC specification to see the SQLState Class value code that is associated with the new SQLExceptions.

Correct SQLState for a DataTruncation on a write operation

We have also fixed a long outstanding JDBC bug so that the SQLState of 22001 is now returned for a DataTruncation Exception during a write operation to a data source.



JDBC 4.0 keeps moving forward

Posted by lancea on February 17, 2006 at 09:23 AM | Permalink | Comments (19)

JDBC 4.0 has just completed public draft review and the EG is working on closing the last few issues. One of the interfaces that I expect to change signficantly is the SQLXML interface. Here is a list of the major features being added to JDBC 4:
  • ROWID Support
  • National Character Set Support
  • Additional SQLException sub classes
  • Improved Blob/Clob support
  • SQL XML support
  • Ease of Development
  • Ability to unwrap implementation classes to make use of vendor specific methods
  • Auto loading of Driver class implementations
  • Connection management enhancements

Some of the features have been enhanced in the current drops of Mustang (part of the specification evolution).

We have also spent a lot of time trying to clarify and improve the javadoc method and interface descriptions as well as various sections of the JDBC paper spec that have resulted in some confusion in the past for developers. We will continue to review and address as many issues that we can prior to the official release of Mustang.

As we wind down the spec work, we will also be focusing on addressing as many outstanding JDBC bugs as possible.



Getting Started using Derby with Glassfish and SJSAS 8.2

Posted by lancea on February 07, 2006 at 11:10 AM | Permalink | Comments (0)

Glassfish and SJSAS 8.2 introduce two new asadmin commands for starting and stopping the Derby Network Server.

The start-database command may be used to start an instance of the Derby network server:

start-database [––dbhost 0.0.0.0] [––dbport 1527] [––dbhome install_dir/derby]
The default value for the host is 0.0.0.0, which allows for Derby to listen on localhost as well as the ip/hostname interfaces.

The value for the dbhome property represents the location of where the derby databases reside. The default is <glassfish/sjsas_HOME>/derby.

You may also use the asadmin command stop-database to shutdown an instance of the Derby network server that is running:

stop-database [––dbhost 0.0.0.0] [––dbport 1527]

The derby configuration that ships with glassfish and SJSAS 8.2 also provides several useful scripts which can assist you with utilizing Derby successfully.

To run these scripts, you need to do the following:

  • set the environment variable DERBY_INSTALL to point to the <glassfish/sjsas_HOME>/derby directory
  • unset your CLASSPATH environment variable
You may also optionally set the following properties:

  • DERBY_SERVER_HOST the host that the network server will listen on (may also be set to 0.0.0.0 to enable all listeners)
  • DERBY_SERVER_PORT the port number for the network server to listen on

The following scripts are available for use in the <glassfish/sjsas_HOME>/derby/frameworks/NetworkServer/bin directory:

  • startNetworkServer.ksh/bat - Script to start the network server
  • stopNetworkServer.ksh/bat - Script to stop the network server
  • ij.ksh/bat - interactive JDBC scripting tool
  • dblook.ksh/bat - Script to view all or part of the DDL for a database
  • sysinfo.ksh/bat - Script to display versioning info regarding the derby environment
  • NetworkServerControl.ksh/bat - Script which provides a means of executing commands on the NetworkServerControl API.

For more information, see the Derby tools and admin guide for additional details on these utilities

Exporting Tables from Pointbase to Derby

Posted by lancea on February 06, 2006 at 04:06 PM | Permalink | Comments (0)

Brian Leonard has a nice article which shows you how to capture the ddl for a table in pointbase and create the same table in Derby using Netbeans 5.0. Another option for doing this is by using the commander tool and the 'unload database' command:
./startcommander.sh
Do you wish to create a new Database. (Yes (Y) or No (N))? [default: N]: 
Enter product to connect with: (Embedded (E) or Server (S))? [default: E]: e
Enter driver to use? [default: [com.pointbase.jdbc.jdbcUniversalDriver]: 
Enter database URL? [default: [jdbc:pointbase:embedded:sample]: 
Enter Username? [default: PBPUBLIC]: 
Enter Password? [default: PBPUBLIC]: 


PointBase Commander 5.2 ECF build 294 size restricted version EMBEDDED

Interactive SQL command language. SunOS/5.9


(C) Copyright 2004 DataMirror Mobile Solutions, Inc. All rights reserved.



Licensed to: Sun_customer_demo_use
For commercial version contact PointBase at: 
pointbase.com
PHONE: 1-877-238-8798 (US & CANADA)
       1-408-961-1100 (International)
WEBSITE: www.pointbase.com

SQL>unload database sampledb.sql;
SQL> unload database sampledb.sql;
SQL> 13 Row(s) Unloaded. (PBPUBLIC.CUSTOMER_TBL)
SQL> 4 Row(s) Unloaded. (PBPUBLIC.DISCOUNT_CODE_TBL)
SQL> 30 Row(s) Unloaded. (PBPUBLIC.MANUFACTURE_TBL)
SQL> 11 Row(s) Unloaded. (PBPUBLIC.MICRO_MARKETS_TBL)
SQL> 9 Row(s) Unloaded. (PBPUBLIC.OFFICE_TBL)
SQL> 4 Row(s) Unloaded. (PBPUBLIC.OFFICE_TYPE_CODE_TBL)
SQL> 15 Row(s) Unloaded. (PBPUBLIC.ORDER_TBL)
SQL> 6 Row(s) Unloaded. (PBPUBLIC.PRODUCT_CODE_TBL)
SQL> 30 Row(s) Unloaded. (PBPUBLIC.PRODUCT_TBL)
SQL> 10 Row(s) Unloaded. (PBPUBLIC.SALES_REP_DATA_TBL)
SQL> 10 Row(s) Unloaded. (PBPUBLIC.SALES_REP_TBL)
SQL> 52 Row(s) Unloaded. (PBPUBLIC.SALES_TAX_CODE_TBL)
SQL> 12 Table(s) Unloaded.
SQL> quit;

The results from executing the 'unload database' command is written in the above example to the file sampledb.sql. The sampledb.sql file contains all of the DDL requried to create the necessary tables and indexes. It also contains the DML to insert the data back into the database. The commander command RUN is intended to be used import the data into another pointbase database using the script that was generated. Here is an example of what the INSERT statments and associated data look like in the generated file:
INSERT INTO "ADVENTURE"."CATEGORY" (
"CATID", "LOCALE", "NAME", "DESCRIPTION", "IMAGEURI" )
VALUES( ?, ?, ?, ?, ? );
{
'ISLAND              ','en_US','Island Adventures','Experience an island paradise in a way fit for your needs.','Island_Adventures.gif'
'JUNGLE              ','en_US','Jungle Adventures','Experience a jungle paradise in a way fit for your needs.','Jungle_Adventures.gif'
'MOUNTAIN            ','en_US','Mountain Adventures','Experience an elevated paradise with a view.','Mountain_Adventures.gif'
'ORBITAL             ','en_US','Orbital Adventures','Experience a vacuum paradise with a beautiful view and where no one can hear you scream.','Space_Adventures.gif'
'WESTERN             ','en_US','Western Adventures','Enjoy the Wild West.','Western_Adventures.gif'
'SOUTH_POLE          ','en_US','South Pole Adventures','Experience a frozen paradise in a way fit for your needs.','SouthPole_Adventures.gif'
};

You could easily edit the file generated from the commander 'unload database' command so that it only consisted of the DDL (it would not be hard to write a program which would process the insert statements and perhaps I will try and find time to do so). As a simple test, I used the unload database command against the pointbase sample database. I edited the script that was generated making the following changes:
  • Removed the phrase Organization Heap from the end of all CREATE Table Statements
  • Removed the COMMIT command
  • Changed the Boolean datatype to be smallint
  • Removed all of the INSERT statements and the associated data
I then created a simple ant script to execute the DDL using the sql target.

I then repeated the same experiment for the sun-appserv-samples database requiring the following additional changes to the generated sql file:

  • Made changes as described above for the sample database
  • removed the create user commands
  • removed the SET PATH commands
  • Changed the Decimal precision from 38 to max of 31
  • changed the float precision from 64 to max of 52
  • The SPECIFIC keyword for CREATE PROCEDURE is not currently supported
  • removed the GRANT commands
Converting Pointbase java procedures to work with Derby requires some changes to the java code as well as to the CREATE PROCEDURE statements. Info on creating Derby Java procedures can be found in the Derby Reference manual. Support for the Boolean datatype should be in the next release of Derby.



Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds