| 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: | Whole Thread | Raw Message | 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
>
| 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() |