diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/OracleLobHandler.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/OracleLobHandler.java
index dd5af5cfc0e..56b34a75db1 100644
--- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/OracleLobHandler.java
+++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/OracleLobHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 the original author or authors.
+ * Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -122,6 +122,7 @@ public class OracleLobHandler extends AbstractLobHandler {
* See SimpleNativeJdbcExtractor's javadoc for details.
* @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor#getNativeConnectionFromStatement
* @see org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor
+ * @see org.springframework.jdbc.support.nativejdbc.OracleJdbc4NativeJdbcExtractor
* @see oracle.jdbc.OracleConnection
*/
public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
@@ -144,20 +145,16 @@ public class OracleLobHandler extends AbstractLobHandler {
* Set whether to agressively release any resources used by the LOB. If set to true
* then you can only read the LOB values once. Any subsequent reads will fail since the resources
* have been closed.
- *
*
Setting this property to true can be useful when your queries generates large
* temporary LOBs that occupy space in the TEMPORARY tablespace or when you want to free up any
* memory allocated by the driver for the LOB reading.
- *
*
Default is false.
- *
* @see oracle.sql.BLOB#freeTemporary
* @see oracle.sql.CLOB#freeTemporary
* @see oracle.sql.BLOB#open
* @see oracle.sql.CLOB#open
* @see oracle.sql.BLOB#close
* @see oracle.sql.CLOB#close
- * @since 3.0
*/
public void setReleaseResourcesAfterRead(boolean releaseResources) {
this.releaseResourcesAfterRead = releaseResources;
@@ -258,27 +255,25 @@ public class OracleLobHandler extends AbstractLobHandler {
/**
* Initialize any LOB resources before a read is done.
- *
- *
This implementation calls
- * BLOB.open(BLOB.MODE_READONLY) or CLOB.open(CLOB.MODE_READONLY)
- * on any non-temporary LOBs
- * if releaseResourcesAfterRead property is set to true.
+ *
This implementation calls BLOB.open(BLOB.MODE_READONLY) or
+ * CLOB.open(CLOB.MODE_READONLY) on any non-temporary LOBs if
+ * releaseResourcesAfterRead property is set to true.
*
This method can be overridden by sublcasses if different behavior is desired. * @param con the connection to be usde for initilization * @param lob the LOB to initialize */ protected void initializeResourcesBeforeRead(Connection con, Object lob) { - if (releaseResourcesAfterRead) { + if (this.releaseResourcesAfterRead) { initOracleDriverClasses(con); try { /* - if (!((BLOB)lob.isTemporary() { + if (!((BLOB) lob.isTemporary() { */ Method isTemporary = lob.getClass().getMethod("isTemporary"); Boolean temporary = (Boolean) isTemporary.invoke(lob); if (!temporary) { /* - ((BLOB)lob).open(BLOB.MODE_READONLY); + ((BLOB) lob).open(BLOB.MODE_READONLY); */ Method open = lob.getClass().getMethod("open", int.class); open.invoke(lob, modeReadOnlyConstants.get(lob.getClass())); @@ -295,44 +290,42 @@ public class OracleLobHandler extends AbstractLobHandler { /** * Release any LOB resources after read is complete. - * *
If releaseResourcesAfterRead property is set to true
* then this implementation calls
* BLOB.close() or CLOB.close()
* on any non-temporary LOBs that are open or
* BLOB.freeTemporary() or CLOB.freeTemporary()
* on any temporary LOBs.
- *
*
This method can be overridden by sublcasses if different behavior is desired.
* @param con the connection to be usde for initilization
* @param lob the LOB to initialize
*/
protected void releaseResourcesAfterRead(Connection con, Object lob) {
- if (releaseResourcesAfterRead) {
+ if (this.releaseResourcesAfterRead) {
initOracleDriverClasses(con);
Boolean temporary = Boolean.FALSE;
try {
/*
- if (((BLOB)lob.isTemporary() {
+ if (((BLOB) lob.isTemporary() {
*/
Method isTemporary = lob.getClass().getMethod("isTemporary");
temporary = (Boolean) isTemporary.invoke(lob);
if (temporary) {
/*
- ((BLOB)lob).freeTemporary();
+ ((BLOB) lob).freeTemporary();
*/
Method freeTemporary = lob.getClass().getMethod("freeTemporary");
freeTemporary.invoke(lob);
}
else {
/*
- if (((BLOB)lob.isOpen() {
+ if (((BLOB) lob.isOpen() {
*/
Method isOpen = lob.getClass().getMethod("isOpen");
Boolean open = (Boolean) isOpen.invoke(lob);
if (open) {
/*
- ((BLOB)lob).close();
+ ((BLOB) lob).close();
*/
Method close = lob.getClass().getMethod("close");
close.invoke(lob);
@@ -358,6 +351,7 @@ public class OracleLobHandler extends AbstractLobHandler {
}
}
+
/**
* LobCreator implementation for Oracle databases.
* Creates Oracle-style temporary BLOBs and CLOBs that it frees on close.
@@ -529,8 +523,8 @@ public class OracleLobHandler extends AbstractLobHandler {
protected Connection getOracleConnection(PreparedStatement ps)
throws SQLException, ClassNotFoundException {
- return (nativeJdbcExtractor != null) ?
- nativeJdbcExtractor.getNativeConnectionFromStatement(ps) : ps.getConnection();
+ return (nativeJdbcExtractor != null ?
+ nativeJdbcExtractor.getNativeConnectionFromStatement(ps) : ps.getConnection());
}
/**
diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/Jdbc4NativeJdbcExtractor.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/Jdbc4NativeJdbcExtractor.java
index 827e482a80e..cc22956202f 100644
--- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/Jdbc4NativeJdbcExtractor.java
+++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/Jdbc4NativeJdbcExtractor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2007 the original author or authors.
+ * Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,10 +26,16 @@ import java.sql.Statement;
/**
* {@link NativeJdbcExtractor} implementation that delegates to JDBC 4.0's
* unwrap method, as defined by {@link java.sql.Wrapper}.
+ * You will typically need to specify a vendor {@link #setConnectionType Connection type}
+ * / {@link #setStatementType Statement type} / {@link #setResultSetType ResultSet type}
+ * to extract, since JDBC 4.0 only actually unwraps to a given target type.
*
- *
Note: Only use this when actually running against a JDBC 4.0 driver, - * with a connection pool that supports the JDBC 4.0 API (i.e. at least accepts - * JDBC 4.0 API calls and passes them through to the underlying driver)! + *
Note: Only use this when actually running against a JDBC 4.0 driver, with a
+ * connection pool that supports the JDBC 4.0 API (i.e. at least accepts JDBC 4.0
+ * API calls and passes them through to the underlying driver)! Other than that,
+ * there is no need for connection pool specific setup. As of JDBC 4.0,
+ * NativeJdbcExtractors will typically be implemented for specific drivers
+ * instead of for specific pools (e.g. {@link OracleJdbc4NativeJdbcExtractor}).
*
* @author Juergen Hoeller
* @since 2.5
@@ -40,29 +46,76 @@ import java.sql.Statement;
*/
public class Jdbc4NativeJdbcExtractor extends NativeJdbcExtractorAdapter {
+ private Class extends Connection> connectionType = Connection.class;
+
+ private Class extends Statement> statementType = Statement.class;
+
+ private Class extends PreparedStatement> preparedStatementType = PreparedStatement.class;
+
+ private Class extends CallableStatement> callableStatementType = CallableStatement.class;
+
+ private Class extends ResultSet> resultSetType = ResultSet.class;
+
+
+ /**
+ * Set the vendor's Connection type, e.g. oracle.jdbc.OracleConnection.
+ */
+ public void setConnectionType(Class extends Connection> connectionType) {
+ this.connectionType = connectionType;
+ }
+
+ /**
+ * Set the vendor's Statement type, e.g. oracle.jdbc.OracleStatement.
+ */
+ public void setStatementType(Class extends Statement> statementType) {
+ this.statementType = statementType;
+ }
+
+ /**
+ * Set the vendor's PreparedStatement type, e.g. oracle.jdbc.OraclePreparedStatement.
+ */
+ public void setPreparedStatementType(Class extends PreparedStatement> preparedStatementType) {
+ this.preparedStatementType = preparedStatementType;
+ }
+
+ /**
+ * Set the vendor's CallableStatement type, e.g. oracle.jdbc.OracleCallableStatement.
+ */
+ public void setCallableStatementType(Class extends CallableStatement> callableStatementType) {
+ this.callableStatementType = callableStatementType;
+ }
+
+ /**
+ * Set the vendor's ResultSet type, e.g. oracle.jdbc.OracleResultSet.
+ */
+ public void setResultSetType(Class extends ResultSet> resultSetType) {
+ this.resultSetType = resultSetType;
+ }
+
+
@Override
protected Connection doGetNativeConnection(Connection con) throws SQLException {
- return (Connection) con.unwrap(Connection.class);
+ return con.unwrap(this.connectionType);
}
@Override
public Statement getNativeStatement(Statement stmt) throws SQLException {
- return (Statement) stmt.unwrap(Statement.class);
+ return stmt.unwrap(this.statementType);
}
@Override
public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException {
- return (PreparedStatement) ps.unwrap(PreparedStatement.class);
+ return ps.unwrap(this.preparedStatementType);
}
@Override
public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException {
- return (CallableStatement) cs.unwrap(CallableStatement.class);
+ return cs.unwrap(this.callableStatementType);
}
@Override
public ResultSet getNativeResultSet(ResultSet rs) throws SQLException {
- return (ResultSet) rs.unwrap(ResultSet.class);
+ return rs.unwrap(this.resultSetType);
}
}
diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/OracleJdbc4NativeJdbcExtractor.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/OracleJdbc4NativeJdbcExtractor.java
new file mode 100644
index 00000000000..123e73c8dd3
--- /dev/null
+++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/OracleJdbc4NativeJdbcExtractor.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2002-2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.jdbc.support.nativejdbc;
+
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+/**
+ * A {@link Jdbc4NativeJdbcExtractor} which comes pre-configured for Oracle's JDBC driver,
+ * specifying the following vendor-specific API types for unwrapping:
+ *
oracle.jdbc.OracleConnection
+ * oracle.jdbc.OracleStatement
+ * oracle.jdbc.OraclePreparedStatement
+ * oracle.jdbc.OracleCallableStatement
+ * oracle.jdbc.OracleResultSet
+ * Note: This will work with any JDBC 4.0 compliant connection pool, without a need for
+ * connection pool specific setup. In other words, as of JDBC 4.0, NativeJdbcExtractors
+ * will typically be implemented for specific drivers instead of for specific pools.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0.5
+ */
+public class OracleJdbc4NativeJdbcExtractor extends Jdbc4NativeJdbcExtractor {
+
+ @SuppressWarnings("unchecked")
+ public OracleJdbc4NativeJdbcExtractor() {
+ try {
+ setConnectionType((Class