I was looking at DERBY-2349, and am looking at the simpler case of just
selecting the BLOB column twice and performing getBinaryStream() on both
columns. The program below does just that and prints the first 10 bytes
of the stream.
With embedded the output is:
4 5 6 7 8 9 10 11 12 13
14 15 16 17 18 19 20 21 22 23
I am done
Two things seem to be happening with embedded.
1) Both getBinaryStream() calls are returning the same stream.
2) The second getBinaryStream() call throws away 4 bytes.
With client the output is:
Exception in thread "main" java.io.IOException: The object is already
closed.
at
org.apache.derby.client.am.CloseFilterInputStream.read(CloseFilterInputStream.java:50)
at DoubleSelect.printNextTen(DoubleSelect.java:53)
at DoubleSelect.main(DoubleSelect.java:43)
0 1 2 3 4 5 6 7 8 9
So with client it looks like the second getBinaryStream() call closes
the first stream but then returns the right result for the second stream.
So my question is, is this a legal case to select the Blob column
twice? Should the embedded driver behave similar to the client and
close and reopen the stream on the second getBinaryStream()?
Thanks for any advice.
Kathey
import java.io.*;
import java.sql.*;
public class DoubleSelect {
public static void main(String[] args) throws Exception {
String url;
if (args.length > 0 && args[0].equals("client"))
{
Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();
url = "jdbc:derby://localhost:1527/testdb;create=true";
} else {
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
url = "jdbc:derby:testdb;create=true";
}
Connection c = DriverManager.getConnection(url);
Statement s = c.createStatement();
try {
s.executeUpdate("drop table t_main");
} catch (SQLException e) {}
s.executeUpdate("CREATE TABLE T_MAIN(" +
"ID INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, " +
"V BLOB(590473235) )");
String ins1 = "INSERT INTO T_MAIN(V) VALUES (?)";
PreparedStatement ps;
ps = c.prepareStatement(ins1);
byte[] bytes = new byte[35000];
for (int i = 0; i < 35000; i++)
bytes[i] = (byte) i ;
ps.setBytes(1, bytes);
ps.executeUpdate();
ps.close();
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 'I', V, ID, V from T_MAIN");
rs.next();
InputStream v1 = rs.getBinaryStream(2);
InputStream v2 = rs.getBinaryStream(4);
printNextTen(v1);
printNextTen(v2);
System.out.println("I am done");
}
private static void printNextTen(InputStream s1)
{
try {
for (int i = 0; i < 10; i++)
{
int val = s1.read();
System.out.print(val + " ");
}
System.out.println("");
} catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}