My Oracle Support Banner

New Jdbc Interfaces for Oracle types (Doc ID 1364193.1)

Last updated on JULY 29, 2019

Applies to:

JDBC - Version 11.2.0.3.0 and later
Information in this document applies to any platform.
Replace types concrete classes with types interfaces.



Details

Deprecation of concrete classes in the next major Oracle JDBC release. Applicable to the all the users who are using Oracle JDBC driver 11.2.0.3 and above.


Background :-

Back in 1996 when Oracle implemented JDBC, the development team chose to create concrete classes instead of using interfaces for Oracle JDBC Types. The documentation recommended users to use these classes. This created the following problems

* Hard coding classes is not a standard way of programming. Types should be declared as interfaces, allowing implementations to evolve over time without breaking binary compatibility
* The classes exposed many of the internal methods
* Hard coding classes make it hard to change the implementation of the classes, defeating the purpose of Object Oriented programming
* Many of the new features are exposed through proxy pattern making almost impossible to implement
such features without breaking backward compatibility.

In Oracle database 11.2.0.3, new interfaces are created for each Oracle type that uses connection. Creating interfaces for all types (including the ones that do not use connection) is planned for the next major RDBMS release.

Concrete classes will now implement a public interface from the oracle.jdbc package and internal interfaces in oracle.jdbc.internal (the latter are not exposed to end users. Users should use methods exposed in java.sql whenever possible for standard compatibility and methods in oracle.jdbc for Oracle specific extensions.

Actions

User Benefits for using the new interfaces :-

The Oracle JDBC team puts a lot of effort in cleaning up the interfaces and making their usage efficient & streamlined with the rest of the Oracle JDBC APIs. Most of the changes are simple replacements and the resulting user code should be more compact and clean. The changes have very low risk in terms of regression. The modified code will easily pick up any future new features without little to no code changes.

What are the affected types?

In Oracle database version 11.2.0.3 only types that have an embedded connection will be replaced by interfaces.

Old types New interfaces
oracle.sql.ARRAY oracle.jdbc.OracleArray
oracle.sql.STRUCT oracle.jdbc.OracleStruct
oracle.sql.CLOB oracle.jdbc.OracleClob
oracle.sql.BLOB oracle.jdbc.OracleBlob
oracle.sql.REF oracle.jdbc.OracleRef
oracle.sql.OPAQUE oracle.jdbc.OracleOpaque


oracle.sql.StructDescriptor, oracle.sql.ArrayDescriptor & oracle.sql.OpaqueDescriptor are removed since they do not serve any purpose that cannot be achieved via the new interfaces.

Changing user code to use new interfaces :-

Changing the code to use new interfaces is trivial, but should be handled with care. The following example applies to oracle.sql.ARRAY but similar changes apply to other types as well. A list of suggested changes are furnished below:

* Import: modify import statements to use the new interfaces (oracle.jdbc) instead of old interfaces (oracle.sql)
* Declaration: use standard Java interfaces for declaration whenever possible. If there is a need to use Oracle extension use the new Oracle interfaces under oracle.jdbc
* Methods: use standard Java interfaces whenever possible
o (Oracle Types): use methods in standard Java interfaces whenever possible. If required use methods from Oracle interfaces under oracle.jdbc
o (Defines): refrain from using Oracle specific methods such as getARRAY, instead use standard Java methods such as getArray or getObject for the ones that does not have standard Java interfaces
o (Binds): Refrain from using Oracle specific methods such as setARRAY, instead use standard Java methods such as setArray or setObject for the ones that does not have standard Java interfaces

Examples of change in usage :-

Import Statement

Replacing import statements is the easiest change it could be done by a simple script, which uses find

find . -name "*.java" -exec egrep ... > files.list
for f in `cat files.list`; do
cat $f |sed 's@^import oracle\.sql\.ARRAY@oracle\.jdbc.OracleArray@g' > /tmp/temp.txt
mv /tmp/temp.txt $f
done


Creating new types

User should use factory methods on oracle.jdbc.OracleConnection. eg: to create an instance of oracle.jdbc.OracleType the user would have done


int[] intArray = { 5, 7, 9};
oracle.sql.ArrayDescriptor aDescriptor = new oracle.sql.ArrayDescriptor("<user>.TYPE1", connection);
oracle.sql.ARRAY array = new oracle.sql.ARRAY(aDescriptor, connection, intArray);

Should be changed to:

int[] intArray = { 5, 7, 9};
java.sql.Array array = connection.createOracleArray("<user>.TYPE1", intArray);

 

NOTE:Oracle does not support anonymous array types and so does not support the standard Connection.createArrayOf method.


Declarations
Declarations that use standard Java interfaces


If the declarations uses standard Java interfaces no change is required

java.sql.Array array = ...

Declarations that use oracle.sql classes If only standard Java methods are used:

oracle.sql.ARRAY array = ...

should be changed to

java.sql.Array array = ...

If Oracle extension methods are used then the declaration should be in the form:

oracle.jdbc.OracleArray array = ...



Methods
Handling methods that use handle Java interfaces


If the methods used and the declaration are from standard JDK then no code change is required.

Example:
java.sql.Array array = resultSet.getArray(...);
Integer[] intArray = (Integer[])array.getArray();


Handling methods that use Oracle extension

If Oracle extension methods are used then the following declaration

Example:
oracle.sql.ARRAY array = resultSet.getARRAY(...);
int[] intArray = array.getIntArray();

should be changed to:

oracle.jdbc.OracleArray array = (oracle.jdbc.OracleArray)resultSet.getArray(...);
int[] intArray = array.getIntArray();


If there is a cast just before using the method then it should be changed as well.

Example:
java.sql.Array array = resultSet.getArray(...);
int[] intArray = ((oracle.sql.ARRAY)array).getIntArray();

Then it should be changed to:

java.sql.Array array = resultSet.getArray(...);
int[] intArray = ((oracle.jdbc.OracleArray)array).getIntArray();


Bind methods
Handling methods that use standard Java bind methods


If the code uses standard Java bind methods no change is required.

Example:
java.sql.Array array = ...
pstmt.setArray(..., array);
or
oracle.jdbc.OracleArray array = ...
pstmt.setArray(..., array);


Handling methods that use Oracle bind methods

If the code uses Oracle specific bind methods then they should be replaced by standard Java bind methods. Use setObject for the methods that do not have specific interfaces in Java. eg: OracleBfile (oracle.sql.BFILE) or OracleOpaque (oracle.sql.OPAQUE).

Define methods (getXXX)
Handling methods that use standard Java define methods


If the code uses standard Java define methods no change is required.

Example:
java.sql.Array array = resultSet.getArray(...);
or
oracle.jdbc.OracleArray array = resultSet.getArray(...);


Handling methods that use Oracle define methods

If the code uses Oracle specific define methods then they should be replaced by standard Java define methods. Use getObject for the methods that do not have specific interfaces in Java. eg: OracleBfile (oracle.sql.BFILE) or OracleOpaque (oracle.sql.OPAQUE).

Example:

oracle.sql.ARRAY array = pstmt.getARRAY(...);

should be replaced by

java.sql.Array array = resultSet.getArray(...);

or

if there is a need to use Oracle extension methods

oracle.jdbc.OracleArray array = (oracle.jdbc.OracleArray) resultSet.getArray(...);


Handling methods that use Oracle Internal

These methods should not be used by user code. There should be an alternative available for every method here. If there are none please contact Oracle JDBC development through support. For the time being you can cast the method to oracle.jdbc.internal.OracleArray to access the method.

Obtaining MetaData


Old implementation used XxxDescriptor to obtain metadata type. This is replaced by oracle.jdbc.OracleTypeMetaData.XXX. Example If the old code looks like this:

Example:
StructDescriptor structDescriptor = new StructDescriptor(...);
ResultSetMetaData structMetaData = structDescriptor.getMetaData();
int columnCount = structMetaData.getColumnCount();
STRUCT struct = new STRUCT(...)


In the new usage there is no need for a descriptor and the declaration will look as follows:

OracleStruct struct = connection.createStruct(...);
oracle.jdbc.OracleTypeMetaData.Struct structMetaData = struct.getMetaData();
int columnCount = structMetaData.getColumnCount();


As it can be seen the new code is neater and more compact compared to the old one.

Contacts

To view full details, sign in with your My Oracle Support account.

Don't have a My Oracle Support account? Click to get started!


In this Document
Details
Actions
Contacts

My Oracle Support provides customers with access to over a million knowledge articles and a vibrant support community of peers and Oracle experts.