Re: [Fwd: [Fwd: Re: solved: fastpath error?]] - Mailing list pgsql-jdbc

From Barry Lind
Subject Re: [Fwd: [Fwd: Re: solved: fastpath error?]]
Date
Msg-id 3D25D4E5.6080004@xythos.com
Whole thread Raw
In response to [Fwd: [Fwd: Re: solved: fastpath error?]]  (Barry Lind <barry@xythos.com>)
List pgsql-jdbc
Michael,

Thanks for the test case.  I have tracked down the bug.  I will commit a
fix to CVS later today.  The problem was that the LargeObject class had
a finalize() method that called the close() method.  The idea being that
if you never explicitly closed the LargeObject it would take care of
that for you during garbage collection.  The problem was that the scope
of a large object is a transaction, thus once you commit the transaction
the large object is no longer valid.  Thus if the LargeObject was
garbage collected after a commit then the call to close() would error
since the large object handle was no longer valid.  The fix is to just
remove the call to close() in the finalize() method and to let the
server release the resource automatically on transaction commit/rollback.

thanks,
--Barry


M. Dietrich wrote:

 >hi barry,
 >
 >On Wed, Jun 19, 2002 at 02:50:36PM -0700, Barry Lind wrote:
 >
 >
 >>If you could send a test case demonstrating the problem I will look
into it.
 >>
 >>
 >see the source. it shows the error after several inserts on my machine.
 >
 >
 >best regards,
 >
 >    michael
 >
 >
 >------------------------------------------------------------------------
 >
 >public class Test
 >{
 >    public static void main(String[] arg) throws Exception
 >    {
 >
    new org.postgresql.Driver();
 >
    java.sql.DriverManager.setLogWriter(new java.io.PrintWriter(System.err));
 >    java.sql.Connection con =
java.sql.DriverManager.getConnection("jdbc:postgresql://localhost:5432/sally",
"sally", "sally");
 >
    con.setAutoCommit(false);
 >    org.postgresql.largeobject.LargeObjectManager lom =
((org.postgresql.Connection)con).getLargeObjectAPI();
 >
    {
 >
        try // dropping the table
 >
        {
 >
        java.sql.Statement statement = con.createStatement();
 >
            statement.executeUpdate("DROP INDEX MD_ITEST");
 >
            statement.executeUpdate("DROP TABLE MD_TEST");
 >
            java.sql.DriverManager.println("testtable dropped");
 >
        }
 >
        catch (java.sql.SQLException e)
 >
        {
 >
            con.rollback();
 >
        }
 >
        // create a test table
 >
    java.sql.Statement statement = con.createStatement();
 >
        statement.executeUpdate("CREATE TABLE MD_TEST (MD_DOC OID, MD_OID BIGINT
NOT NULL)");
 >
        statement.executeUpdate("CREATE UNIQUE INDEX MD_ITEST ON MD_TEST(MD_OID)");
 >
        java.sql.DriverManager.println("testtable created");
 >
        statement.close();
 >
        con.commit();
 >
    }
 >
    // insert 1000 rows
 >    long i = 0;
 >
    while (i++ < 1000)
 >
    {
 >
        //System.runFinalization(); System.gc(); // comment out these to see the
error even earlier
 >
        java.sql.DriverManager.println("id = " + i);
 >
        // create blob out of class-file (everything else suits fine)
 >
    java.io.InputStream in = new java.io.BufferedInputStream(new
java.io.FileInputStream("Test.class"));
 >
    int loid = lom.create(org.postgresql.largeobject.LargeObjectManager.READ
| org.postgresql.largeobject.LargeObjectManager.WRITE);
 >
        java.sql.DriverManager.println("loid = " + loid);
 >
    org.postgresql.largeobject.LargeObject blob = lom.open(loid,
org.postgresql.largeobject.LargeObjectManager.WRITE);
 >
    int s;
 >
    byte buf[] = new byte[2048];
 >
        while ((s = in.read(buf, 0, buf.length)) > 0)
 >
            blob.write(buf, 0, s);
 >
        blob.close();
 >
        in.close();
 >
        // prepare insert statement
 >
    java.sql.PreparedStatement preparedStatement =
con.prepareStatement("INSERT INTO MD_TEST (MD_OID, MD_DOC) VALUES(?, ?)");
 >
        // bind vars
 >
        preparedStatement.setLong(1, i);
 >
    java.sql.Blob b = new
org.postgresql.largeobject.PGblob((org.postgresql.Connection)con, loid);
 >
        preparedStatement.setBlob(2, b);
 >
        // exec insert
 >
    int no = preparedStatement.executeUpdate();
 >
        preparedStatement.close();
 >
        java.sql.DriverManager.println("row created");
 >
        con.commit(); // move this commit out of the loop and everything's fine...
 >
    }
 >
    con.close();
 >
    java.sql.DriverManager.println("test succeeded");
 >    }
 >}
 >
 >
 >------------------------------------------------------------------------
 >
 ><?xml version="1.0"?>
 ><project name="training" default="all" basedir=".">
 >    <property name="name" value="training" />
 >    <property name="build.compiler" value="modern" />
 >    <target name="all" depends="compile" />
 >    <target name="compile">
 >
    <javac
 >
        srcdir="."
 >
        debug="yes"
 >
        classpath=".:/home/mdt/cd/devpgjdbc2.jar"
 >
    />
 >    </target>
 >    <target name="run" depends="compile">
 >
    <java
 >
        classname="Test"
 >
        fork="yes"
 >
        classpath=".:/home/mdt/cd/devpgjdbc2.jar"
 >
    />
 >    </target>
 >    <target name="javadoc" depends="compile">
 >
    <javadoc
 >
        sourcepath="."
 >
        packagenames="*"
 >
        destdir="javadoc"
 >
    />
 >    </target>
 ></project>
 >
 >






pgsql-jdbc by date:

Previous
From: Tomisław Kityński
Date:
Subject: PreparedStatement and DB default values
Next
From: Barry Lind
Date:
Subject: Re: Retrieving binary data