db-derby-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ralph Richard Cook <ralph.richard.c...@gmail.com>
Subject Length of binary streams must match length parameter(?)
Date Mon, 04 Oct 2004 21:13:04 GMT
I'm not sure if this is a bug or proper behavior, but here goes...

For performance reasons, I'd like to reuse a byte array when inserting BLOBs
into a derby database. I'm inserting with a PreparedStatement, making a new
ByteArrayInputStream around a reused byte[] buffer, depending on the length
parameter of the PreparedStatement.setBinaryStream method to say how many
bytes to use out of the stream. However, if the length parameter doesn't match
the actual length of the buffer used in the ByteArrayInputStream then
derby complains, loudly. Here is a small sample program to show what I mean,
followed by the Exception I get from it. Line 45 is the third call to
PreparedStatement.execute.

All that's needed to compile and run this in the classpath is derby.jar.

Is this an actual bug, or are these two numbers supposed to match in all
JDBC implementations? If they are supposed to match, why bother with the
length parameter at all?

Thanks for looking at this.

import java.io.*;
import java.sql.*;

public class DerbyBlobTest  {
    public static void main(String[] args) {
        try {
            byte[] buf = new byte[10];

            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
            Connection connection = 
                DriverManager.getConnection("jdbc:derby:blobtest;create=true");

            Statement stmt = connection.createStatement();
            stmt.executeUpdate("CREATE TABLE BLOBTEST ( ID VARCHAR(20) " 
                               + "NOT NULL PRIMARY KEY, DATA BLOB)");
            stmt.close();

            connection.setAutoCommit(false);

            PreparedStatement pstmt = 
                connection.prepareStatement("INSERT INTO BLOBTEST " 
                                            + "(ID, DATA) VALUES(?, ?)");

            /* One to show it works... */
            pstmt.setString(1, "BLOB1");
            pstmt.setBinaryStream(2, new ByteArrayInputStream(buf), 10);
            pstmt.execute();
            connection.commit();

            /* 
             * Another one to prove it wasn't a coincidence, we can
             * re-use the PreparedStatement, etc.
             */
            pstmt.setString(1, "BLOB2");
            pstmt.setBinaryStream(2, new ByteArrayInputStream(buf), 10);
            pstmt.execute();
            connection.commit();

            /* 
             * This one fails because we want to use fewer bytes than 
             * is in the buffer. The third call to execute is Line 45.
             */
            pstmt.setString(1, "BLOB3");
            pstmt.setBinaryStream(2, new ByteArrayInputStream(buf), 5);
            pstmt.execute();
            connection.commit();
            pstmt.close();
            connection.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}



ERROR XSDA4: An unexpected exception was thrown
        at org.apache.derby.iapi.error.StandardException.newException(StandardException.java)
        at org.apache.derby.impl.store.raw.data.InsertOperation.<init>(InsertOperation.java)
        at org.apache.derby.impl.store.raw.data.LoggableActions.actionInsert(LoggableActions.java)
        at org.apache.derby.impl.store.raw.data.BasePage.insertNoOverflow(BasePage.java)
        at org.apache.derby.impl.store.raw.data.BasePage.insertAtSlot(BasePage.java)
        at org.apache.derby.impl.store.raw.data.StoredPage.insertAtSlot(StoredPage.java)
        at org.apache.derby.impl.store.raw.data.BasePage.insert(BasePage.java)
        at org.apache.derby.impl.store.access.heap.HeapController.doInsert(HeapController.java)

        at org.apache.derby.impl.store.access.heap.HeapController.insertAndFetchLocation(HeapController.java)
        at org.apache.derby.impl.sql.execute.RowChangerImpl.insertRow(RowChangerImpl.java)
        at org.apache.derby.impl.sql.execute.InsertResultSet.normalInsertCore(InsertResultSet.java)
        at org.apache.derby.impl.sql.execute.InsertResultSet.open(InsertResultSet.java)
        at org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java)
        at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java)
        at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(EmbedPreparedStatement.java)
        at org.apache.derby.impl.jdbc.EmbedPreparedStatement.execute(EmbedPreparedStatement.java)
        at DerbyBlobTest.main(DerbyBlobTest.java:45)

Mime
View raw message