Skip to content

Commit d5f34ed

Browse files
committed
Correctly handle NVARCHAR, LONGNVARCHAR and NCLOBs
Issue: SPR-16154
1 parent a88c47a commit d5f34ed

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,16 @@ public abstract class StatementCreatorUtils {
6868
* System property that instructs Spring to ignore {@link java.sql.ParameterMetaData#getParameterType}
6969
* completely, i.e. to never even attempt to retrieve {@link PreparedStatement#getParameterMetaData()}
7070
* for {@link StatementCreatorUtils#setNull} calls.
71-
* <p>The default is "false", trying {@code getParameterType} calls first and falling back to
71+
* <p>The effective default is "false", trying {@code getParameterType} calls first and falling back to
7272
* {@link PreparedStatement#setNull} / {@link PreparedStatement#setObject} calls based on well-known
7373
* behavior of common databases. Spring records JDBC drivers with non-working {@code getParameterType}
7474
* implementations and won't attempt to call that method for that driver again, always falling back.
7575
* <p>Consider switching this flag to "true" if you experience misbehavior at runtime, e.g. with
7676
* a connection pool setting back the {@link PreparedStatement} instance in case of an exception
7777
* thrown from {@code getParameterType} (as reported on JBoss AS 7).
78+
* <p>Note that this flag is "true" by default on Oracle 12c since there can be leaks created by
79+
* {@code getParameterType} calls in such a scenario. You need to explicitly set the flag to
80+
* "false" in order to enforce the use of {@code getParameterType} against Oracle drivers.
7881
*/
7982
public static final String IGNORE_GETPARAMETERTYPE_PROPERTY_NAME = "spring.jdbc.getParameterType.ignore";
8083

@@ -339,10 +342,12 @@ private static void setValue(PreparedStatement ps, int paramIndex, int sqlType,
339342
else if (inValue instanceof SqlValue) {
340343
((SqlValue) inValue).setValue(ps, paramIndex);
341344
}
342-
else if (sqlType == Types.VARCHAR || sqlType == Types.NVARCHAR ||
343-
sqlType == Types.LONGVARCHAR || sqlType == Types.LONGNVARCHAR) {
345+
else if (sqlType == Types.VARCHAR || sqlType == Types.LONGVARCHAR ) {
344346
ps.setString(paramIndex, inValue.toString());
345347
}
348+
else if (sqlType == Types.NVARCHAR || sqlType == Types.LONGNVARCHAR) {
349+
ps.setNString(paramIndex, inValue.toString());
350+
}
346351
else if ((sqlType == Types.CLOB || sqlType == Types.NCLOB) && isStringValue(inValue.getClass())) {
347352
String strVal = inValue.toString();
348353
if (strVal.length() > 4000) {
@@ -364,8 +369,13 @@ else if ((sqlType == Types.CLOB || sqlType == Types.NCLOB) && isStringValue(inVa
364369
logger.debug("JDBC driver does not support JDBC 4.0 'setClob(int, Reader, long)' method", ex);
365370
}
366371
}
367-
// Fallback: regular setString binding
368-
ps.setString(paramIndex, strVal);
372+
// Fallback: setString or setNString binding
373+
if (sqlType == Types.NCLOB) {
374+
ps.setNString(paramIndex, strVal);
375+
}
376+
else {
377+
ps.setString(paramIndex, strVal);
378+
}
369379
}
370380
else if (sqlType == Types.DECIMAL || sqlType == Types.NUMERIC) {
371381
if (inValue instanceof BigDecimal) {

0 commit comments

Comments
 (0)