Search code examples
javajdbcfirebirdjaybird

How to set bind values to NULL with Firebird's jaybird JDBC driver?


I'm running into a bit of a situation in corner cases when binding null to a PreparedStatement with Firebird's jaybird JDBC driver. Here's a sample statement:

Class.forName("org.firebirdsql.jdbc.FBDriver");

// Observe the "local" in the connection string!
Connection con = DriverManager.getConnection(
    "jdbc:firebirdsql:local:C:/data/firebird/test.db", "TEST", "TEST");

// With this connection, I'm not able to reproduce the issue:
Connection con1 = DriverManager.getConnection(
    "jdbc:firebirdsql:localhost:C:/data/firebird/test.db", "TEST", "TEST");

PreparedStatement stmt = con.prepareStatement(
  "SELECT cast(? as varchar(1)) FROM rdb$database");
stmt.setObject(1, null);
ResultSet rs = stmt.executeQuery();
rs.next();
System.out.println(rs.getString(1));
System.out.println(rs.wasNull());

The output of the above program is

>
> false

The first line being an empty string. It really should be

> null
> true

Changing this line ...

stmt.setObject(1, null);

... into any of these lines ...

stmt.setString(1, null);
stmt.setNull(1, Types.VARCHAR);

... doesn't help either. A workaround is to inline null literals in SQL statements, instead of binding them to the prepared statement. What am I missing?

Details:

  • Database: Firebird WI-V2.5.1.26351
  • JDBC driver: jaybird-2.2.0
  • Java version: JDK 1.6.0_24
  • OS: Windows 7 x64
  • JDBC Connection String: See above.

Solution

  • Apparently, this is a bug in the JDBC driver:

    http://tracker.firebirdsql.org/browse/JDBC-271

    It only appears when using this sort of connection URL:

    // Observe the "local" in the connection string!
    Connection con = DriverManager.getConnection(
        "jdbc:firebirdsql:local:C:/data/firebird/test.db", "TEST", "TEST");
    

    Not with this sort:

    // With this connection, I'm not able to reproduce the issue:
    Connection con1 = DriverManager.getConnection(
        "jdbc:firebirdsql:localhost:C:/data/firebird/test.db", "TEST", "TEST");