Search code examples
javadatabaseblobderby

Stream has already been read and end-of-file reached and cannot be re-used


I have created a Derby database, created a table containing a BLOB column 'pic' as one of the columns.

Now I am trying to store .jpg file from local to this BLOB field. I have written the code below, where I am trying to update BLOB column of every row with a local Image and then read the table once again and fetch the BLOB and store back on folder on local.

public static void main(String[] args) {
    try {
        Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
        String dbURL = "jdbc:derby:D:/software/derby/derby/bin/MyDbTest";
        Connection conn1 = DriverManager.getConnection(dbURL);
        if (conn1 != null) {
            System.out.println("Connected to database #1");
        }
        PreparedStatement stmt = conn1
                .prepareStatement("update PRACTICEEMPLOYEEDB set pic = ?");
        File f1  =new File(
                "D:\\Users\\abkale\\Downloads\\asd.jpg");
        InputStream in = new FileInputStream(f1);
        stmt.setBinaryStream(1, in,f1.length());
        stmt.execute();   //LINE 1 :Place where exception in being thrown
        conn1.commit();

        Statement s = conn1.createStatement();
        ResultSet rs1=s.executeQuery("select * from practiceemployeedb");
        int i=0;
        while(rs1.next()){
            //Some code to read columns and print/store
        }

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
}

But in above code i am getting below error on //LINE 1 ::

Connected to database #1
java.sql.SQLException: An unexpected exception was thrown
    at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.Util.seeNextException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement.execute(Unknown Source)
    at derby.ConnectionProvider.main(ConnectionProvider.java:33)
Caused by: ERROR XSDA4: An unexpected exception was thrown
    at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
    at org.apache.derby.impl.jdbc.SQLExceptionFactory.wrapArgsForTransportAcrossDRDA(Unknown Source)
    ... 11 more
Caused by: java.io.EOFException: Stream has already been read and end-of-file reached and cannot be re-used.
    at org.apache.derby.iapi.types.RawToBinaryFormatStream.read(Unknown Source)
    at org.apache.derby.impl.store.raw.data.MemByteHolder.write(Unknown Source)
    at org.apache.derby.impl.store.raw.data.RememberBytesInputStream.fillBuf(Unknown Source)
    at org.apache.derby.impl.store.raw.data.StoredPage.logColumn(Unknown Source)
    at org.apache.derby.impl.store.raw.data.StoredPage.logRow(Unknown Source)
    at org.apache.derby.impl.store.raw.data.UpdateOperation.writeOptionalDataToBuffer(Unknown Source)
    at org.apache.derby.impl.store.raw.data.UpdateOperation.<init>(Unknown Source)
    at org.apache.derby.impl.store.raw.data.LoggableActions.actionUpdate(Unknown Source)
    at org.apache.derby.impl.store.raw.data.StoredPage.doUpdateAtSlot(Unknown Source)
    at org.apache.derby.impl.store.raw.data.BasePage.updateAtSlot(Unknown Source)
    at org.apache.derby.impl.store.access.conglomerate.GenericConglomerateController.replace(Unknown Source)
    at org.apache.derby.impl.sql.execute.RowChangerImpl.updateRow(Unknown Source)
    at org.apache.derby.impl.sql.execute.UpdateResultSet.collectAffectedRows(Unknown Source)
    at org.apache.derby.impl.sql.execute.UpdateResultSet.open(Unknown Source)
    at org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(Unknown Source)
    at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown Source)
    ... 4 more

I don't understand what I am doing wrong can anyone help?


Solution

  • You cannot update multiple rows with the same stream. Create a where clause to select a single row in your statement and it should work.

    This bug was reported to only fail with the embedded driver, and working with the client driver. More info here.

    Also, according to this, this problem only affects versions 10.9.1.0 and 10.10.2.0. Has this resurfaced on a later version or are you using one of these?