Skip to Main Content

Java Database Connectivity (JDBC)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

ResultSet.getString() on 8000 character CLOB breaks

Nikolay MetchevJan 12 2015 — edited Jan 12 2015

Hello,

We have encountered a very strange bug. If you have a CLOB column in an Oracle and you store an 8000 character string in there then when reading it using oracle jdbc driver

using ResultSet.getString() something goes wrong with the encoding. The string appears to be interleaved with the char '\0'. If the CLOB stores 4000 characters or 8001 characters the bug doesn't reproduce.

This only happens for us when running on linux (Centos 7) with both Oracle Java 7 and Oracle Java 8 and using either ojdbc7 or ojdbc6.

When running in Windows this bug doesn't happen. Charset.defaultCharset() returns UTF-8 on both windows and Linux.

Also if we revert to using the oracle 11.2.0.4 jdbc driver this bug doesn't reproduce either.

versions:

Database:

Oracle Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

With the Partitioning, Oracle Label Security, OLAP, Data Mining

and Real Application Testing options

JDBC

(Oracle JDBC driver 12.1.0.2.0)

Comments

Joe Weinstein-Oracle

Seems like a clear driver issue. File an SR with Oracle. If you provide a small standalone program and it's output

that demonstrates the problem, you'll get the fastest response...

Nikolay Metchev

Thanks Joe,

Do I need to have some sort of Oracle Agreement in order to file an SR with Oracle? How do I file it?

Joe Weinstein-Oracle

Ideally you'd be an oracle customer, and then be able to contact support for the service request.

If you are not, but can cobble up the example I suggested (ideally it makes it's own table,

and populates it as needed, and produces the output you'r concerned with, then I will see if I

can file it for you. Getting a fix for it though, will be much slower if you are not a paying support

customer...

Nikolay Metchev

We are in the process of getting some sort of agreement with Oracle. It is a slow and painful process.

Thanks Joe for all your help.

Here is some code to help you reproduce the problem. You will need to update the username, password and tnsName strings to get it to work for you:

----sql---

create table test  (

TEST     CLOB        NOT NULL

)

------------

----java----

import java.io.IOException;

import java.io.Reader;

import java.nio.charset.Charset;

import java.sql.Clob;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import oracle.jdbc.pool.OracleDataSource;

public class Test {

  public static void main(String[] args) throws SQLException, IOException  {

    try(Connection conn = createConn()) {

      PreparedStatement prepareStatement = conn.prepareStatement("insert into test values (?)");

      StringBuilder strBuilder = new StringBuilder(8000);

      for(int i = 0 ; i < 8000 ; i++) {

        strBuilder.append("1");

      }

      prepareStatement.setString(1,strBuilder.toString());

      prepareStatement.executeUpdate();

      Statement createStatement = conn.createStatement();

      ResultSet rs = createStatement.executeQuery("Select * from test");

      System.out.println(Charset.defaultCharset());

      while(rs.next()) {

        String str = rs.getString(1);

        Clob clob = rs.getClob(1);

        Reader characterStream = clob.getCharacterStream();

        char[] cbuf = new char[20];

        characterStream.read(cbuf);

        System.out.println(new String(cbuf).substring(1, 20));

        System.out.println(clob.getSubString(1, 19));

        System.out.println(str.substring(1, 20));//this string will be displayed as 10 1's instead of 20 1's

        System.out.println(str.length());

      }

    }

  }

  private static final String TNS_ADMIN_PROPERTY = "oracle.net.tns_admin";

  private static final String TNS_ADMIN_ENV = "TNS_ADMIN";

  public static Connection createConn() throws SQLException {

    if (System.getProperty(TNS_ADMIN_PROPERTY) == null) {

      String tnsAdminVal = System.getenv(TNS_ADMIN_ENV);

      if (tnsAdminVal != null) {

        System.setProperty(TNS_ADMIN_PROPERTY, tnsAdminVal);

      } else {

        System.out.println("No Oracle TNS config found - expected to find " + TNS_ADMIN_PROPERTY + " system property or " +

                 TNS_ADMIN_ENV + " environment variable.");

      }

    }

    String tnsName = "tnsName";

    String user = "user";

    OracleDataSource ods = new OracleDataSource();

    ods.setDriverType("thin");

    ods.setTNSEntryName(tnsName);

    ods.setUser(user);

    ods.setPassword("password");

    return ods.getConnection();

  }

}

----------------------------------------------------------------------------------

Joe Weinstein-Oracle

Great. Now, if you will add printlns to the program that show the relevant environment (OS, charset, etc)

and show me the output here, for two runs, one where it works, and one where it doesn't that will

complete the package I can send to JDBC guys.

Nikolay Metchev

The code was outputing the default charset already (UTF-8). I added the OS as well. Here is the output:

---------Working output---------

Windows 8.1

UTF-8

1111111111111111111

1111111111111111111

1111111111111111111

8000

--------------------------------------------------

-----------Broken Output--------------------

Linux

UTF-8

1111111111111111111

1111111111111111111

1111111111

8000

-----------------------------------------------------

unknown-7404

Do I need to have some sort of Oracle Agreement in order to file an SR with Oracle? How do I file it?

Whoever owns that database better already have a support agreement so have them file it.

Oracle Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

That upgrade version is ONLY available to paid support customers.

If the org using that DB version does NOT have a support agreement then they should not even have that version.

Nikolay Metchev

Hello rp0428,

We are a startup that hasn't yet got any clients. The database I am using is to create a demo, not a production system. Any production system will of course be fully licenced. We are in talks with Oracle to try and get an agreement in place.

1 - 8
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Feb 9 2015
Added on Jan 12 2015
8 comments
12,330 views