11/*
2- * Copyright 2002-2012 the original author or authors.
2+ * Copyright 2002-2014 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
2626import java .sql .ResultSet ;
2727import java .sql .ResultSetMetaData ;
2828import java .sql .SQLException ;
29+ import java .sql .SQLFeatureNotSupportedException ;
2930import java .sql .Statement ;
3031import java .sql .Types ;
31-
3232import javax .sql .DataSource ;
3333
3434import org .apache .commons .logging .Log ;
3535import org .apache .commons .logging .LogFactory ;
3636
3737import org .springframework .jdbc .CannotGetJdbcConnectionException ;
3838import org .springframework .jdbc .datasource .DataSourceUtils ;
39+ import org .springframework .util .ClassUtils ;
3940
4041/**
4142 * Generic utility methods for working with JDBC. Mainly for internal use
@@ -53,6 +54,10 @@ public abstract class JdbcUtils {
5354 public static final int TYPE_UNKNOWN = Integer .MIN_VALUE ;
5455
5556
57+ // Check for JDBC 4.1 getObject(int, Class) method - available on JDK 7 and higher
58+ private static final boolean getObjectWithTypeAvailable =
59+ ClassUtils .hasMethod (ResultSet .class , "getObject" , int .class , Class .class );
60+
5661 private static final Log logger = LogFactory .getLog (JdbcUtils .class );
5762
5863
@@ -134,74 +139,74 @@ public static Object getResultSetValue(ResultSet rs, int index, Class<?> require
134139 return getResultSetValue (rs , index );
135140 }
136141
137- Object value = null ;
138- boolean wasNullCheck = false ;
142+ Object value ;
139143
140144 // Explicitly extract typed value, as far as possible.
141145 if (String .class .equals (requiredType )) {
142- value = rs .getString (index );
146+ return rs .getString (index );
143147 }
144148 else if (boolean .class .equals (requiredType ) || Boolean .class .equals (requiredType )) {
145149 value = rs .getBoolean (index );
146- wasNullCheck = true ;
147150 }
148151 else if (byte .class .equals (requiredType ) || Byte .class .equals (requiredType )) {
149152 value = rs .getByte (index );
150- wasNullCheck = true ;
151153 }
152154 else if (short .class .equals (requiredType ) || Short .class .equals (requiredType )) {
153155 value = rs .getShort (index );
154- wasNullCheck = true ;
155156 }
156157 else if (int .class .equals (requiredType ) || Integer .class .equals (requiredType )) {
157158 value = rs .getInt (index );
158- wasNullCheck = true ;
159159 }
160160 else if (long .class .equals (requiredType ) || Long .class .equals (requiredType )) {
161161 value = rs .getLong (index );
162- wasNullCheck = true ;
163162 }
164163 else if (float .class .equals (requiredType ) || Float .class .equals (requiredType )) {
165164 value = rs .getFloat (index );
166- wasNullCheck = true ;
167165 }
168166 else if (double .class .equals (requiredType ) || Double .class .equals (requiredType ) ||
169167 Number .class .equals (requiredType )) {
170168 value = rs .getDouble (index );
171- wasNullCheck = true ;
172169 }
173- else if (byte [] .class .equals (requiredType )) {
174- value = rs .getBytes (index );
170+ else if (BigDecimal .class .equals (requiredType )) {
171+ return rs .getBigDecimal (index );
175172 }
176173 else if (java .sql .Date .class .equals (requiredType )) {
177- value = rs .getDate (index );
174+ return rs .getDate (index );
178175 }
179176 else if (java .sql .Time .class .equals (requiredType )) {
180- value = rs .getTime (index );
177+ return rs .getTime (index );
181178 }
182179 else if (java .sql .Timestamp .class .equals (requiredType ) || java .util .Date .class .equals (requiredType )) {
183- value = rs .getTimestamp (index );
180+ return rs .getTimestamp (index );
184181 }
185- else if (BigDecimal .class .equals (requiredType )) {
186- value = rs .getBigDecimal (index );
182+ else if (byte [] .class .equals (requiredType )) {
183+ return rs .getBytes (index );
187184 }
188185 else if (Blob .class .equals (requiredType )) {
189- value = rs .getBlob (index );
186+ return rs .getBlob (index );
190187 }
191188 else if (Clob .class .equals (requiredType )) {
192- value = rs .getClob (index );
189+ return rs .getClob (index );
193190 }
194191 else {
195192 // Some unknown type desired -> rely on getObject.
196- value = getResultSetValue (rs , index );
193+ if (getObjectWithTypeAvailable ) {
194+ try {
195+ return rs .getObject (index , requiredType );
196+ }
197+ catch (SQLFeatureNotSupportedException ex ) {
198+ logger .debug ("JDBC driver does not support JDBC 4.1 'getObject(int, Class)' method" , ex );
199+ }
200+ catch (AbstractMethodError err ) {
201+ logger .debug ("JDBC driver does not implement JDBC 4.1 'getObject(int, Class)' method" , err );
202+ }
203+ }
204+ // Fall back to getObject without type specification...
205+ return getResultSetValue (rs , index );
197206 }
198207
199- // Perform was-null check if demanded (for results that the
200- // JDBC driver returns as primitives).
201- if (wasNullCheck && value != null && rs .wasNull ()) {
202- value = null ;
203- }
204- return value ;
208+ // Perform was-null check if necessary (for results that the JDBC driver returns as primitives).
209+ return (rs .wasNull () ? null : value );
205210 }
206211
207212 /**
@@ -234,15 +239,12 @@ public static Object getResultSetValue(ResultSet rs, int index) throws SQLExcept
234239 else if (obj instanceof Clob ) {
235240 obj = rs .getString (index );
236241 }
237- else if (className != null &&
238- ("oracle.sql.TIMESTAMP" .equals (className ) ||
239- "oracle.sql.TIMESTAMPTZ" .equals (className ))) {
242+ else if ("oracle.sql.TIMESTAMP" .equals (className ) || "oracle.sql.TIMESTAMPTZ" .equals (className )) {
240243 obj = rs .getTimestamp (index );
241244 }
242245 else if (className != null && className .startsWith ("oracle.sql.DATE" )) {
243246 String metaDataClassName = rs .getMetaData ().getColumnClassName (index );
244- if ("java.sql.Timestamp" .equals (metaDataClassName ) ||
245- "oracle.sql.TIMESTAMP" .equals (metaDataClassName )) {
247+ if ("java.sql.Timestamp" .equals (metaDataClassName ) || "oracle.sql.TIMESTAMP" .equals (metaDataClassName )) {
246248 obj = rs .getTimestamp (index );
247249 }
248250 else {
@@ -371,9 +373,6 @@ public static boolean supportsBatchUpdates(Connection con) {
371373 catch (SQLException ex ) {
372374 logger .debug ("JDBC driver 'supportsBatchUpdates' method threw exception" , ex );
373375 }
374- catch (AbstractMethodError err ) {
375- logger .debug ("JDBC driver does not support JDBC 2.0 'supportsBatchUpdates' method" , err );
376- }
377376 return false ;
378377 }
379378
0 commit comments