0

So I'm having a big issue with CLOBs and Oracle. Up until now, the database my company has been using for this one client has just been passed simple Strings through a PreparedStatement. This has been fine, because those Strings have all been less than 4,000 characters. We just discovered that limit exists. Not 100% sure why, believe it's something related to how CLOBs behave. Anyway, I have been assigned to go into the code and fix this.

So, at the moment, the PreparedStatement has its parameters assigned through a very simple process:

((PreparedStatement) stmt).setObject(fieldIndex++, fieldInfo.value);

This has worked well enough for now, but obviously not so much going forward.

Anyway, so my first thought was to try and use some of the PreparedStatement methods related to CLOBs. fieldInfo.value is a declared type of Object, with its actual type set dynamically. Up until now, it's been kept as a String, as I said, so I decided I would just change its type and then use one of the PreparedStatement methods to assign it.

I've tried the following value types & PreparedStatement methods:

if(fieldInfo.value instanceof InputStream){
    ((PreparedStatement) stmt).setBinaryStream(fieldIndex++, (InputStream) fieldInfo.value);
}

if(fieldInfo.value instanceof Reader){
    ((PreparedStatement) stmt).setCharacterStream(fieldIndex++, (Reader) fieldInfo.value);
}

if(fieldInfo.value instanceof Clob){
    ((PreparedStatement) stmt).setClob(fieldIndex++, (Clob) fieldInfo.value);
}

I'm obviously not calling all of those in a row, those are just examples of what I've tried separately.

Every one of those has the same result: AbstractMethodError. Upon researching that exception, I saw that the issue is most likely my JDBC driver. Except... as far as I can tell, I'm on the right one. I've tried this with ojdbc6 & ojdbc7, same error. I've scoured my classpath, and every directory in the project, for any indication that an older jar is hiding there, and I can't seem to find one.

Does anyone have any idea what could be happening?

craigmiller160
  • 5,751
  • 9
  • 41
  • 75

2 Answers2

0

Wow, what a weird issue. There was an old oracle driver buried inside another jar that had been sitting around for years. Ah, the wonders of legacy applications that haven't had a good code rebasing ever.

Anyway, any mods that see this can close this question.

craigmiller160
  • 5,751
  • 9
  • 41
  • 75
0

I don't know what a command do you want to execute in your code, is it INSERT, UPDATE or some other command ?
However I simply followed the manual "JDBC Developer's Guide", a topic "Working with LOBs and BFILEs" ==> http://docs.oracle.com/cd/E11882_01/java.112/e16548/oralob.htm#JJDBC28535
and everything worked fine.
They wrote in the documentation that:

In Oracle Database 11g release 2 (11.2), the setBytes, setBinaryStream, setString, setCharacterStream, and setAsciiStream methods of PreparedStatement are extended to enhance the ability to work with BLOB, CLOB, and NCLOB target columns.

They say that setString must work with strings > 4000 char, then I've created this simple test case, I used ojdbc6 driver (for Oracle 11.2), see below:

CREATE TABLE myclob(
  id int,
  myclob clob
);
================================
public static void main(String ...x) throws SQLException{
    OracleDataSource ods = new OracleDataSource();
    ods.setURL("jdbc:oracle:thin:@//localhost:1521/orcl");
    ods.setUser("test");
    ods.setPassword("test");

    Connection con = ods.getConnection();

    PreparedStatement stmt = con.prepareStatement("INSERT INTO myclob( id, myclob) VALUES (?, ?)");

    StringBuffer str = new StringBuffer();
    for(int i = 0; i<1000; i++)
        str.append("Very long line number = " + i);
    System.out.println( "The length is: " + str.length());
    stmt.setInt(1, 2);
    stmt.setString(2, str.toString());

    stmt.executeUpdate();
    con.commit();

    stmt.close();
    con.close();
}

================================
select length( m.myclob), m.*
from myclob m;

LENGTH(M.MYCLOB)         ID MYCLOB                                                                         
---------------- ---------- --------------------------------------------------------------------------------
           26890          2 Very long line number = 0Very long line number = 1Very long line number = 2Very 
krokodilko
  • 35,300
  • 7
  • 55
  • 79