Skip to content

Commit 3908804

Browse files
committed
StatementCreatorUtils uses setClob/setNClob with stream argument in case of typed String value exceeding 4000 characters (for Oracle compatibility)
Issue: SPR-12240
1 parent 3046fdd commit 3908804

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.jdbc.core;
1818

19+
import java.io.StringReader;
1920
import java.io.StringWriter;
2021
import java.math.BigDecimal;
2122
import java.math.BigInteger;
@@ -24,6 +25,7 @@
2425
import java.sql.DatabaseMetaData;
2526
import java.sql.PreparedStatement;
2627
import java.sql.SQLException;
28+
import java.sql.SQLFeatureNotSupportedException;
2729
import java.sql.Types;
2830
import java.util.Arrays;
2931
import java.util.Calendar;
@@ -319,10 +321,33 @@ else if (inValue instanceof SqlValue) {
319321
((SqlValue) inValue).setValue(ps, paramIndex);
320322
}
321323
else if (sqlType == Types.VARCHAR || sqlType == Types.NVARCHAR ||
322-
sqlType == Types.LONGVARCHAR || sqlType == Types.LONGNVARCHAR ||
323-
((sqlType == Types.CLOB || sqlType == Types.NCLOB) && isStringValue(inValue.getClass()))) {
324+
sqlType == Types.LONGVARCHAR || sqlType == Types.LONGNVARCHAR) {
324325
ps.setString(paramIndex, inValue.toString());
325326
}
327+
else if ((sqlType == Types.CLOB || sqlType == Types.NCLOB) && isStringValue(inValue.getClass())) {
328+
String strVal = inValue.toString();
329+
if (strVal.length() > 4000) {
330+
// Necessary for older Oracle drivers, in particular when running against an Oracle 10 database.
331+
// Should also work fine against other drivers/databases since it uses standard JDBC 4.0 API.
332+
try {
333+
if (sqlType == Types.NCLOB) {
334+
ps.setNClob(paramIndex, new StringReader(strVal), strVal.length());
335+
}
336+
else {
337+
ps.setClob(paramIndex, new StringReader(strVal), strVal.length());
338+
}
339+
return;
340+
}
341+
catch (AbstractMethodError err) {
342+
logger.debug("JDBC driver does not implement JDBC 4.0 'setClob(int, Reader, long)' method", err);
343+
}
344+
catch (SQLFeatureNotSupportedException ex) {
345+
logger.debug("JDBC driver does not support JDBC 4.0 'setClob(int, Reader, long)' method", ex);
346+
}
347+
}
348+
// Fallback: regular setString binding
349+
ps.setString(paramIndex, strVal);
350+
}
326351
else if (sqlType == Types.DECIMAL || sqlType == Types.NUMERIC) {
327352
if (inValue instanceof BigDecimal) {
328353
ps.setBigDecimal(paramIndex, (BigDecimal) inValue);

0 commit comments

Comments
 (0)