Thread: Help - lo_close: invalid large obj descriptor

Help - lo_close: invalid large obj descriptor

From
Toby
Date:
I've read the docs, I've searched the web.

I'm running PGSql 7.3.4 under Cygwin 1.3.22.1, using the latest JDBC v3 drivers (jar file).
Accessing the database works fine, but when I try to write to a newly created LargeObject it always fails with

org.postgresql.util.PSQLException - FastPath call returned ERROR:  lo_write: invalid large obj descriptor (0)

The code below illustrates this.

The code is actually going to be used within a Tomcat webapp, but I had to use Jdbc3ConnectionPool since that was the only pool that returned connections that were castable to a PGConnection. I get the same error from inside and outside Tomcat. Thought the error might be related to permissions writing large objects so I tried the following which didn't help.

        GRANT ALL ON "pg_largeobject" TO "web";

So I suspect the problem is related to using a pooled connection. Can someone shed some light?


import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.SQLException;

import org.postgresql.PGConnection;
import org.postgresql.jdbc3.Jdbc3ConnectionPool;
import org.postgresql.largeobject.LargeObject;
import org.postgresql.largeobject.LargeObjectManager;

public class TestHarness
{
   
public static void main(String[] args)
    {
        LargeObject lo =
null;
        Connection conn =
null;
       
try
        {
           
//get a connection that's PGConnection-castable.
            //PoolingDataSource- tried 'n died
            //Jdbc3PoolingDataSource- tried 'n died
            Jdbc3ConnectionPool source = new Jdbc3ConnectionPool();
            source.setServerName(
"ash");
            source.setDatabaseName(
"adserver");
            source.setUser(
"web");
            source.setPassword(
"web");
            source.setDefaultAutoCommit(
false);

           
//just to be sure - it always says true so that's good
            conn = source.getConnection();
            System.out.println(conn.getAutoCommit());

           
//this only works for connections from Jdbc3ConnectionPool
            PGConnection pgconn = (PGConnection)conn;

           
//create the largeobject and prepare to write to it
            LargeObjectManager lom = pgconn.getLargeObjectAPI();
           
int oid = lom.create(LargeObjectManager.READ | LargeObjectManager.WRITE);
            lo = lom.open(oid, LargeObjectManager.WRITE);

           
//the thing to write
            File file = new File("D:\\downloads\\images\\banner.GIF");
            FileInputStream fis =
new FileInputStream(file);

           
//prepare a buffer (small enough to force multiple loop iterations
            //so we test it properly)
            byte buff[] = new byte[1024];

           
//now write the image
            int bytes_read;
           
while ((bytes_read = fis.read(buff, 0, buff.length)) > 0)
            {
                System.out.println(
"bytes_read=" + bytes_read);
               
//this fails with the following error
                //org.postgresql.util.PSQLException - FastPath call returned ERROR:  lo_write: invalid large obj descriptor (0)
                lo.write(buff, 0, bytes_read);
            }

           
//clean up
            fis.close();
            System.out.println(
"done");
        }
       
catch (Exception e)
        {
            System.out.println(e.getClass().getName() +
" - " + e.getMessage());
        }
       
finally
        {
           
if (lo != null)    try{lo.close();}catch (SQLException e){}
           
if (conn != null) try{conn.close();}catch (SQLException e){}
        }
    }
}