Closed
Description
Anthony Yeracars opened SPR-12240 and commented
- INSERT INTO table (col1, col2)
- SELECT ?, ?
- FROM DUAL
- fails with ORA-01461 when col1 or col2 is an NCLOB and the associated placeholder parameter is of length > 4000
- while:
- INSERT INTO table (col1, col2)
- VALUES (?, ?)
- works. However, it is unclear that knowing that INSERT VALUES works is relevant.
- (Note: the actual use case is as follows, which means that using INSERT VALUES as a workaround is not satisfactory:)
- INSERT INTO table (col1, col2)
- SELECT ?, ?
- FROM DUAL
- WHERE NOT EXISTS (SELECT * FROM table WHERE col1 = ?)
- (in this case, col1 is an ID column, as per this test case)
- The bug is present in StatementCreatorUtils.setValue(), where Spring JDBC assumes that a CLOB that is small enough can be established with a call to setString() (or,
- if too large, with a call to setObject()). The correct behavior, as demonstrated below, is to call setClob(new StringReader(inValue)) (or, if an NCLOB, then
- setNClob()---in fact, for our use case, we use only NCLOBs). This is consistent with Oracle documentation
- (see http://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html), which states, for setString(), the following: "Sets the designated parameter to the
- given Java String value. The driver converts this to an SQL VARCHAR or LONGVARCHAR value (depending on the argument's size relative to the driver's limits on VARCHAR
- values) when it sends it to the database." An argument could be made that Oracle's driver should undertake this conversion automatically (i.e., change the String to a
- StringReader or equivalent), although that is a harder road than a Spring update, not to mention that the Oracle's PreparedStatement implementation does not actually
- have enough context to make this determination.
- This test case uses Java 7 and Spring 3.1.0; code inspection shows that the same bug is present in Spring 4.1.0.
- Fails on Oracle drivers 11.2.0.2, 11.2.0.3, 11.2.0.4; server versions 10, 11.1, 11.2
Affects: 4.1 GA
Attachments:
- ORA01461.java (9.43 kB)
Issue Links:
- Support for Types.NCLOB in SqlLobValue to simplify use with NamedParameterJdbcTemplate. [SPR-11938] #16555 Support for Types.NCLOB in SqlLobValue to simplify use with NamedParameterJdbcTemplate.
- PreparedStatement#setBlob(int, InputStream) is not supported in DefaultLobCreator [SPR-12265] #16870 PreparedStatement#setBlob(int, InputStream) is not supported in DefaultLobCreator
- Java boolean is not handled correctly when used with Oracle JDBC driver [SPR-14116] #18688 Java boolean is not handled correctly when used with Oracle JDBC driver
- Oracle 12c JDBC driver throws inconsistent exception from getParameterType (affecting setNull calls) [SPR-13825] #18398 Oracle 12c JDBC driver throws inconsistent exception from getParameterType (affecting setNull calls)
Referenced from: commits 3908804