2016-10-19 6 views
0

TL; DR: HiveとMySqlの両方のJDBCを併用すると問題がありますか?HiveとMySqlの両方のJDBCドライバを使用しています

私は、MySql JDBCドライバを使用していくつかのSQLクエリを実行し、その後、Hive JDBCを使用して別のHiveクエリを送信するアプリケーションに取り組んでいます。この例外がスローされた後

com.mysql.cj.core.exceptions.WrongArgumentException: Connector/J cannot handle a database URL of type 'jdbc:hive2:'. 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
    at com.mysql.cj.core.exceptions.ExceptionFactory.createException(ExceptionFactory.java:54) 
    at com.mysql.cj.core.conf.url.ConnectionUrl$Type.fromValue(ConnectionUrl.java:149) 
    at com.mysql.cj.core.conf.url.ConnectionUrl.getConnectionUrlInstance(ConnectionUrl.java:193) 
    at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:195) 
    at java.sql.DriverManager.getConnection(DriverManager.java:664) 
    at java.sql.DriverManager.getConnection(DriverManager.java:247) 
    at company.services.HiveV2Provider.createConnection(HiveProvider.scala:105) 
    at company.services.HiveProvider$class.loanConnection(HiveProvider.scala:66) 

今すぐクエリが正常に実行されます。今起こっていただきました

は、コードがハイブは、それがこの例外をスロークエリ実行しようとしたときにMySQLのクエリは、正常に機能していることです。

MySqlとHiveの両方のドライバをロードしているので、MySqlドライバはこのクエリを最初に実行しようとしていますが、Hive URLに遭遇するとこの例外がスローされ、Hiveドライバがそれを見て実行しますクエリが正常に

これは、私は、MySQLのコードを実行する方法を示します。

val query = ... // query is created here 
var mysqlConn: Connection = null 
var stmt: Statement = null 
try { 
    Class.forName("com.mysql.jdbc.Driver") 
    mysqlConn = DriverManager.getConnection(mysqlAddress, username, password) 
    stmt = mysqlConn.createStatement() 
    val rs = stmt.executeQuery(query) 
    val returnVal = someResultSetHandlingFunction(rs) 
    rs.close() 
    returnVal 
} catch { 
    case NonFatal(e) => 
    logWarning(s"Failed to execute query on: $mysqlAddress", e) 
    throw e 
} finally { 
    if (mysqlConn != null) { 
    mysqlConn.close() 
    } 
} 

マイハイブコードはのみのドライバ名と同じになります。org.apache.hive.jdbc.HiveDriver(そしてそれはjdbc:hive2://someurlと通信)

のバージョン:

  • ハイブは、ハイブ-JDBC-1.1.0-cdh5.7.1
  • MySQLは避けるためにどのような方法があるかどう誰もが知ってい6.0.4

のmysql-コネクタ-javaのですこの例外を受け取りますか? 2つの異なるJDBCドライバをロードするのは問題がありますか?

  • 私は直接JDBCを使用するには、そのおそらくない最高のものを知っているが、私は何かをチェックしている:私は、これはわずか数の明確化問題

    すべきではないという印象を受ける他のやや似質問で読みますおよびJDBCは、私はスカラ座を使用してい

  • このタスクのための罰金ですが、私はそれがこの問題のために事前に

おかげで重要とは思わない

答えて

1

私はほとんど私の質問だから、問題はおそらくthisバグに関連している

に答えるのを忘れ:

なぜあなたは次のようにURIをチェックした後、特定のJDBCドライバへの呼び出しを委任していません。私がこの問題に直面していたとき、スタックトレース印刷であり、実際の失敗ではないことに気がつかなかったので、予想以上に問題はありませんでした。

hereが表示されているように、特定のバージョンでこの問題が修正されたので、私はmysqlバージョンを5.1.9に変更しました。スタックトレースの失敗はなくなりました。

誰かが私はMS SQL ServerのJDBCドライバーと同じ問題に直面していたこの

乾杯

+1

私の解決策(SQLServerドライバ、同じエラー)にコメントしていましたが、答えが長すぎます。別の答えとして掲示される。多分それはハイブのドライバーケースにも合っているでしょう。 – jfneis

+0

私は明らかにすでに動作していますが、これらの問題はデバッグに迷惑をかけるので、あなたの答えが将来の開発者に役立つかもしれないことを願っています:) – Gideon

0
Class.forName("com.mysql.jdbc.Driver") 

は、JDBCドライバをDriverManagerに登録します。その後、ハイブ接続URI

DriverManager.getConnection(mysqlAddress, username, password) 

の例外は、このケースでは期待されて置きます。

if (uri.contains("hive")){ 
     //call Hive JDBC 
    } 

    else if (uri.contains("mysql")){ 
     //call Mysql JDBC 
    } 
+0

私は誤字を犯しましたが、私の意図したところは、Hive JDBCコードは別のドライバ名を使用しています(私は質問を更新しました)ので、Hive要求を送信する前に正しいHiveDriverをロードしています。 – Gideon

+0

2つの質問 - 1.個々にそれぞれを使用できるのですか? 2.あなたのコードフローは、ハイブ接続を意味します。uriは '{Class.forName(" com.mysql.jdbc.Driver ")'コードブロックには行きませんか? –

+0

1.両方とも別々に動作します。今でも使用されても例外はスローされますが、それでも動作します。私はコードの実行中に例外を見るのが好きではありません 2.フローコードは別です。これらは2つの全く異なるクラスなので、URIがtryブロックに入る機会はありません – Gideon

1

に、よりエレガントな解決策を持っている場合は聞いている場合、私は幸せになるでしょう。同じエラーが記録されましたが、すべて正常に機能しました。

のJDBC API 4.0ではthis Microsoft page:

によると、DriverManager.getConnectionメソッドは、自動的にJDBCドライバをロードするように拡張 です。したがって、アプリケーション は、sqljdbc4.jar、sqljdbc41.jar、またはsqljdbc42.jar クラスライブラリを使用するときに、 ドライバを登録またはロードするためにClass.forNameメソッドを呼び出す必要はありません。

Class.forNameを削除してみましたが、ちょうどDriverManager.getConnectionと呼ばれました。物事はうまくいっているし、もはや迷惑なエラーは出てこない。

私は、ドライバ自身が有効なJDBCドライバとして登録する "META-INF/services/java.sql.Driver"ファイルを含んでいなければならないと思うので、必ずしもあなたのためではなくSQL Server Driverユーザーそれは行く方法です。

ところで、DriverManager.getConnectionは、ドライブを初めて呼び出すときにかなり長い時間(6〜7秒)かかることに気付きました。それ以降の通話はOKです。アプリケーションによっては問題があるかもしれません。

関連する問題