jdbcdatabricksjdbctemplate

Databricks & JdbcTemplate query error when parameter is a boolean


On Java 17, latest databricks-jdbc dependency, Spring 5.3.20

When I use JdbcTemplate to query a table and one of the parameters is a boolean, I get an error message:

Query: SELECT rowkey, sendReminder FROM SOME_TABLE WHERE sendReminder = ? Param: true (boolean)

Error: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [SELECT rowkey, sendReminder FROM SOME_TABLE WHERE sendReminder = ?]; SQL state [HY000]; error code [500352]; [Databricks][JDBCDriver](500352) Error getting the parameter data type: HIVE_PARAMETER_QUERY_DATA_TYPE_ERR_NON_SUPPORT_DATA_TYPE; nested exception is java.sql.SQLException: [Databricks][JDBCDriver](500352) Error getting the parameter data type: HIVE_PARAMETER_QUERY_DATA_TYPE_ERR_NON_SUPPORT_DATA_TYPE

```at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1542)```

When I run the same query but use a PraparedStatement in my Java code, the query works.

Has anyone seen this before? Known issue?

Thanks!


Solution

  • The data type is Boolean - unless I'm mistaken, it is supported because I did the 2 following experiments:

    1. Used queryForList with an extra argument, manually specifying type of arguments, where argTypes uses java.sql.Types.BOOLEAN (num value == 16)

    jdbcTemplate.queryForList(sql, args.toArray(), argTypes);

    1. Using a prepared statement

    ResultSet resultSet = null; try (PreparedStatement preparedStatement = dataSource.getConnection().prepareStatement(sql)) { preparedStatement.setBoolean(1, (Boolean) args.get(0));

    Both work fine. I did a bit of deep debugging into JdbcTemplate source code and it seems like when using only queryForList(sql, args), the argument types in case of boolean gets marked as "java.sql.Types.BIT". This is acceptable according to JDBC specs but Databricks can't handle that. And it is not wrong on the side of spring-jdbc jdbcTemplate(sql, args), that just takes its "best guess".