[infinispan-issues] [JBoss JIRA] (ISPN-2082) JdbcStringBasedCacheStore: ORA-24816 when storing BLOB values > 4000 bytes
Ryan Scharer (JIRA)
jira-events at lists.jboss.org
Mon Jul 16 14:17:06 EDT 2012
[ https://issues.jboss.org/browse/ISPN-2082?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12706161#comment-12706161 ]
Ryan Scharer commented on ISPN-2082:
------------------------------------
Whew... thought I was going crazy because I couldn't reproduce the problem. Turns out the missing secret ingredient is an unusually long key (> 1000 chars). I'm guessing you were testing with much more prosaic keys. The following test case illustrates the problem trivially. The first prepared statement succeeds, and the second fails. The only difference is the insertion order.
--- SQL
create user clob_testcase identified by password;
grant connect, resource to clob_testcase;
create table clob_testcase.test (
KEY VARCHAR2(2000) NOT NULL,
VALUE BLOB,
TSTAMP NUMBER(10),
PRIMARY KEY (KEY)
);
--- JAVA
package com.test.clob;
import java.io.ByteArrayInputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class Main {
public static void main(String[] args) throws Exception {
char[] keyChars = new char[1001];
for (int i = 0; i < keyChars.length; i++) {
keyChars[i] = 'x';
}
char[] key2Chars = new char[1001];
for (int i = 0; i < keyChars.length; i++) {
key2Chars[i] = 'y';
}
byte[] bytes = new byte[18001];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = 'z';
}
Class.forName("oracle.jdbc.OracleDriver");
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@racload0:1521/gen", "clob_testcase", "password");
//this succeeds
PreparedStatement pstmt = con.prepareStatement("insert into test(tstamp, key, value) values(?,?,?)");
pstmt.setLong(1, -1);
pstmt.setString(2, String.valueOf(keyChars));
pstmt.setBinaryStream(3, new ByteArrayInputStream(bytes), bytes.length);
pstmt.executeUpdate();
pstmt.close();
//this fails
pstmt = con.prepareStatement("insert into test(tstamp, value, key) values(?,?,?)");
pstmt.setLong(1, -1);
pstmt.setBinaryStream(2, new ByteArrayInputStream(bytes), bytes.length);
pstmt.setString(3, String.valueOf(key2Chars));
pstmt.executeUpdate();
pstmt.close();
con.close();
}
}
> JdbcStringBasedCacheStore: ORA-24816 when storing BLOB values > 4000 bytes
> --------------------------------------------------------------------------
>
> Key: ISPN-2082
> URL: https://issues.jboss.org/browse/ISPN-2082
> Project: Infinispan
> Issue Type: Bug
> Components: Loaders and Stores
> Affects Versions: 5.1.5.FINAL
> Environment: OS X 10.7.4, JDK 1.7.0u4
> Reporter: Ryan Scharer
> Assignee: Tristan Tarrant
> Fix For: 5.2.0.ALPHA2, 5.2.0.FINAL
>
>
> I've configured a JdbcStringBasedCacheStore with a VARCHAR(4000) key column and a BLOB value column. If I try to store a BLOB value of less than 4000 bytes, everything works fine. If the value is greater, the cache store fails with ORA-24816. This occurs because the BLOB column is not the last one in the PreparedStatement SQL as the Oracle driver requires. My current, sad workaround is to clone the JdbcStringBasedCacheStore implementation and write my own insert/update SQL in storeLockSafe(). This works fine, but obviously isn't ideal from an upgrade point of view. Simply overriding storeLockSafe() isn't an option due to all the private fields.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.jboss.org/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the infinispan-issues
mailing list