db-derby-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Craig Russell <craig.russ...@sun.com>
Subject Re: Length of binary streams must match length parameter(?)
Date Tue, 05 Oct 2004 15:52:14 GMT
Hi Ralph,

Have you tried using the constructor of ByteArrayInputStream that takes  
an offset and length?

Instead of:
>             pstmt.setBinaryStream(2, new ByteArrayInputStream(buf), 5);
try:
                pstmt.setBinaryStream(2, new ByteArrayInputStream(buf,  
0, 5), 5);

Craig

On Oct 4, 2004, at 2:13 PM, Ralph Richard Cook wrote:

> 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(StandardExce 
> ption.java)
>         at  
> org.apache.derby.impl.store.raw.data.InsertOperation.<init>(InsertOpera 
> tion.java)
>         at  
> org.apache.derby.impl.store.raw.data.LoggableActions.actionInsert(Logga 
> bleActions.java)
>         at  
> org.apache.derby.impl.store.raw.data.BasePage.insertNoOverflow(BasePage 
> .java)
>         at  
> org.apache.derby.impl.store.raw.data.BasePage.insertAtSlot(BasePage.jav 
> a)
>         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(HeapCon 
> troller.java)
>
>         at  
> org.apache.derby.impl.store.access.heap.HeapController.insertAndFetchLo 
> cation(HeapController.java)
>         at  
> org.apache.derby.impl.sql.execute.RowChangerImpl.insertRow(RowChangerIm 
> pl.java)
>         at  
> org.apache.derby.impl.sql.execute.InsertResultSet.normalInsertCore(Inse 
> rtResultSet.java)
>         at  
> org.apache.derby.impl.sql.execute.InsertResultSet.open(InsertResultSet. 
> java)
>         at  
> org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPrepa 
> redStatement.java)
>         at  
> org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStateme 
> nt.java)
>         at  
> org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(Embe 
> dPreparedStatement.java)
>         at  
> org.apache.derby.impl.jdbc.EmbedPreparedStatement.execute(EmbedPrepared 
> Statement.java)
>         at DerbyBlobTest.main(DerbyBlobTest.java:45)
>
Craig Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!

Mime
View raw message