Re: Recent backward compatibility break in PreparedStatement.setObject()

From: Dave Cramer <pg(at)fastcrypt(dot)com>
To: Adam Rauch <adam(at)labkey(dot)com>
Cc: List <pgsql-jdbc(at)postgresql(dot)org>
Subject: Re: Recent backward compatibility break in PreparedStatement.setObject()
Date: 2015-12-30 21:54:40
Message-ID: CADK3HH+kA8JvUvPAVTKcguvh67LoDc-R_021Xd4Qggq=pYY4pA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-jdbc

No, this was not intentional.

Thanks for the report!

Dave Cramer

davec(at)postgresintl(dot)com
www.postgresintl.com

On 30 December 2015 at 16:45, Adam Rauch <adam(at)labkey(dot)com> wrote:

> The PostgreSQL JDBC driver recently changed PreparedStatement behavior
> with calls such as setObject(index, value, Types.VARCHAR). Previously, the
> driver would call value.toString() before binding all VARCHAR values...
> meaning any object could be passed as "value." In recent updates (e.g.,
> 9.4.1207), most non-String values now result in an exception:
>
> Exception in thread "main" org.postgresql.util.PSQLException: Cannot
> convert an instance of XXX to type String
> at
> org.postgresql.jdbc.PgStatement.cannotCastException(PgStatement.java:1813)
> at
> org.postgresql.jdbc.PgStatement.cannotCastException(PgStatement.java:1809)
> at
> org.postgresql.jdbc.PgStatement.castToString(PgStatement.java:1805)
> at org.postgresql.jdbc.PgStatement.setObject(PgStatement.java:1540)
> at org.postgresql.jdbc.PgStatement.setObject(PgStatement.java:1818)
> at PGTest.main(PGTest.java:25)
>
> This seems to have broken during the refactor to support binary transfer
> for setObject(), https://github.com/pgjdbc/pgjdbc/issues/328. Was the
> behavior change intentional? If so, it should probably be documented (e.g.,
> I didn't see any mention in the change log). If not, I'd suggest going back
> to calling value.toString() for all types. I'm sure ours is not the only
> application that relies on this long-standing (>10 years) PostgreSQL JDBC
> behavior. FWIW, other JDBC drivers call toString() in this situation.
>
> Here's a contrived example that demonstrates the behavior change. This
> code snippet runs fine in 1201 but fails with the exception above in 1207.
>
> Object param = new Object() {public String toString() {return "tables";}};
> try (PreparedStatement stmt = conn.prepareStatement("SELECT * FROM information_schema.tables WHERE table_name = ?"))
> {
> stmt.setObject(1, param, Types.VARCHAR);
>
> try (ResultSet rs = stmt.executeQuery())
> {
> while (rs.next())
> System.out.println(rs.getString(1));
> }
> }
>
>
> Thanks,
> Adam
>

In response to

Responses

Browse pgsql-jdbc by date

  From Date Subject
Next Message John Harvey 2015-12-30 23:06:37 Re: Are pgrpm changes for JDBC discussed here before submission?
Previous Message Adam Rauch 2015-12-30 21:45:17 Recent backward compatibility break in PreparedStatement.setObject()