Use commons-dbutils with hive-jdbc

hive-jdbcと一緒にcommons-dbutilsを使う場合。

環境

  • commons-dbutils 1.6
  • hive-jdbc-1.1.0-cdh5.7.1

DbUtilsでgetParameterMetaDataの呼び出しをスキップ

hive-jdbcと一緒にcommons-dbutilsを使う場合、hive-jdbcではjava.sql.PreparedStatement#getParameterMetaData()をサポートしていない(上記環境でのバージョン)ので、以下のようにQueryRunnerの初期化時にgetParameterMetaDataをサポートしていない旨を渡してあげる必要があります。

package sample;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler;

public class HiveJdbcTool {
	static final String HIVE_URI = "jdbc:hive2://localhost:10000/default";

	static {
		try {
			Class.forName("org.apache.hive.jdbc.HiveDriver");
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e);
		}
	}
	public static void main(String[] args) throws Exception {
		try (Connection conn = DriverManager.getConnection(HIVE_URI, "hive", "")) {
			// "true" indicates that JDBC does not support "getParameterMetaData()" method.
			QueryRunner runner = new QueryRunner(true);
			ResultSetHandler<List<Object[]>> rsh = new ArrayListHandler();
			List<Object[]> results = runner.query(conn, "show databases", rsh);
			results.stream()
			  .map(columns -> columns[0])
			  .forEach(System.out::println);
		}
	}
}

以下は、org.apache.commons.dbutils.AbstractQueryRunner#fillStatementの呼び出し部分で、QueryRunner#queryメソッドの内部で呼ばれます。

...
    public void fillStatement(PreparedStatement stmt, Object... params)
            throws SQLException {

        // check the parameter count, if we can
        ParameterMetaData pmd = null;
        if (!pmdKnownBroken) { // trueでスキップ
            pmd = stmt.getParameterMetaData();
            int stmtCount = pmd.getParameterCount();
            int paramsCount = params == null ? 0 : params.length;

            if (stmtCount != paramsCount) {
                throw new SQLException("Wrong number of parameters: expected "
                        + stmtCount + ", was given " + paramsCount);
            }
        }
...

pmdKnownBrokenがtrueの場合はパラメータ数のチェック処理がスキップされます。QueryRunnerの初期化時に該当変数にtrueを指定しなかった場合、hive-jdbcではgetParameterMetaDataの呼び出しで例外がスローされ以下のようなエラーが表示されます。

Exception in thread "main" java.sql.SQLException: Method not supported Query: show databases Parameters: []
	at org.apache.commons.dbutils.AbstractQueryRunner.rethrow(AbstractQueryRunner.java:392)
	at org.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:351)
	at org.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:226)
	at sample.HiveJdbcTool.main(HiveJdbcTool.java:25)

参考リンク

  • https://commons.apache.org/proper/commons-dbutils/apidocs/index.html
  • https://issues.apache.org/jira/browse/HIVE-6992
  • https://github.com/apache/hive/blob/master/jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java#L209

byebyehaikikyou

日記やIT系関連のネタ、WordPressに関することなど様々な事柄を書き付けた雑記です。ITエンジニア経験があるのでプログラミングに関することなどが多いです。

シェアする

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

コメントする

Translate »