Hive,JDBC,ResultSet。 TTransportException:SASL身份验证未完成

时间:2018-07-24 16:14:55

标签: jdbc hive

我连接到配置单元,并从表的行中获取我的数据的ID。当我:连接到配置单元,发送请求并获得响应时,问题就不会发生。但是,当我从ResultSet获得ID时,我得到一个异常:org.apache.thrift.transport.TTransportException:SASL身份验证未完成。为什么会出现这种异常,需要采取什么措施来避免这种异常?对不起,我的英语不好。

这是我的附属类,用于创建配置单元连接并发送请求:

public class HiveDataSearcher implements AutoCloseable {
private static final String hiveDriverName = "org.apache.hive.jdbc.HiveDriver";

static {
    try {
        Class.forName(hiveDriverName);
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    }
}

private Connection hiveConnection;

private String tableName;
private String whereBody;

public HiveDataSearcher(String url, String login, String password) {
    try {
        hiveConnection = DriverManager.getConnection(url, login, password);
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }

    this.tableName = "";
    this.whereBody = "";
}

public HiveDataSearcher(Connection hiveConnection) {
    Objects.requireNonNull(hiveConnection, "hiveConnection");

    this.hiveConnection = hiveConnection;

    this.tableName = "";
    this.whereBody = "";
}

public String getTableName() {
    return tableName;
}

public HiveDataSearcher setTableName(String tableName) {
    Objects.requireNonNull(tableName, "tableName");

    this.tableName = tableName;

    return this;
}

public String getWhereBody() {
    return whereBody;
}

public HiveDataSearcher setWhereBody(String whereBody) {
    Objects.requireNonNull(whereBody, "whereBody");

    this.whereBody = whereBody;

    return this;
}

public ResultSet select(String ... selectParams) {
    return select(Arrays.asList(selectParams));
}

public ResultSet select(Iterable<String> selectParams) {
    String request = prepareRequest(selectParams);
    ResultSet response;

    try {
        response = hiveConnection
                .createStatement()
                .executeQuery(request);
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }

    return response;
}

private String prepareRequest(Iterable<String> selectParams) {
    return new StringBuilder()
            .append("select").append(' ').append(selectParamsToHiveFormat(selectParams)).append(' ')
            .append("from").append(' ').append(tableName).append(' ')
            .append("where").append(' ').append(whereBody)
            .toString();
}

private String selectParamsToHiveFormat(Iterable<String> selectParams) {
    StringBuilder formattedSelectParams = new StringBuilder();

    for (String selectedParam : selectParams) {
        formattedSelectParams.append('\'').append(selectedParam).append('\'').append(',');
    }

    if (formattedSelectParams.length() == 0) {
        formattedSelectParams.append('*');
    } else {
        formattedSelectParams.deleteCharAt(formattedSelectParams.length() - 1);
    }

    return formattedSelectParams.toString();
}

public void close() {
    if (hiveConnection != null) {
        try {
            hiveConnection.close();
        } catch (SQLException e) {
            //nothing to do, just close connection
        } finally {
            hiveConnection = null;
        }
    }
}

}

这是我连接到蜂巢的代码:

private static final String HIVE_URL = <hive url>;
private static final String HIVE_LOGIN = <hive login>;
private static final String HIVE_PASSWORD = <hive password>;

private static final String[] SEARCH_FIELDS = new String[] {"rowkey"};

private List<String> getIdsFromHive(String tableName, String whereBody) {
    ResultSet hiveResponse;

    try (HiveDataSearcher searcher = new HiveDataSearcher(HIVE_URL, HIVE_LOGIN, HIVE_PASSWORD)) {
        hiveResponse = searcher
                .setTableName(tableName)
                .setWhereBody(whereBody)
                .select(SEARCH_FIELDS);
    }

    List<String> ids = new ArrayList<>();

    try {
        while (hiveResponse.next()) { // in this place throw TTransportException
            ids.add(hiveResponse.getString(SEARCH_FIELDS[0]));
        }
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }

    return ids;
}

1 个答案:

答案 0 :(得分:0)

在我的情况下,此异常的原因是在关闭语句之前关闭了连接。因此,我建议您检查是否正确维护了连接。

这是我的代码,希望它能启发您一些东西:

代码错误,在关闭语句之前先关闭连接:

    Connection connection = null;
    Statement statement = null;
    try {
        connection = HIVEUTILS.getConnection();
        statement = connection.createStatement();
        statement.execute("DROP TABLE IF EXISTS tbl1");
        statement.execute("CREATE TABLE `tbl1` (`id` int)");
        statement.execute("INSERT INTO tbl1 VALUES(1)");
    }finally {
        if (connection != null){
            connection.close();
        }
        if (statement != null){
            statement.close(); // exception occur here.
        }
    }

正确的关闭顺序为:关闭resultSet(如果有)->关闭语句->关闭连接。

    Connection connection = null;
    Statement statement = null;
    try {
        connection = HIVEUTILS.getConnection();
        statement = connection.createStatement();
        statement.execute("DROP TABLE IF EXISTS tbl1");
        statement.execute("CREATE TABLE `tbl1` (`id` int)");
        statement.execute("INSERT INTO tbl1 VALUES(1)");
    }finally {
        if (statement != null){
            statement.close(); // change the order
        }
        if (connection != null){
            connection.close();
        }
    }