TL; DR: 同时使用Hive和MySql JDBC是否有问题?
我正在使用MySql JDBC驱动程序执行多个SQL查询的应用程序,之后它还使用Hive JDBC发送另一个Hive查询。
现在发生的事情是MySql查询工作正常,当代码尝试执行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和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()
}
}
我的Hive代码看起来只与驱动程序名称相同:org.apache.hive.jdbc.HiveDriver
(并且它与jdbc:hive2://someurl
进行通信)
版本:
有人知道是否有办法避免收到此异常?加载2个不同的JDBC驱动程序是否有问题?阅读其他类似的问题,我得到的印象是这不应该是一个问题
只是一些澄清:
提前致谢
答案 0 :(得分:1)
我差点忘了回答我的问题
所以问题可能与this bug有关。当我遇到这个问题时,我没有注意到它只是一个堆栈跟踪打印而不是实际的故障,因此它比我预期的问题少。
无论如何,我看到在某些特定版本中这个问题已得到修复,因为你可以看到here所以我只是将我的mysql版本改为5.1.9(因为我不需要更高版本的任何特定的并且堆栈跟踪失败消失了。
如果有人对此有更优雅的解决方案,我会很高兴。
干杯
答案 1 :(得分:1)
我遇到了与MS SQL Server JDBC Driver相同的问题。记录了同样的错误,但一切正常。
在JDBC API 4.0中,DriverManager.getConnection方法是 增强以自动加载JDBC驱动程序。因此,应用程序 不需要调用Class.forName方法来注册或加载 使用sqljdbc4.jar,sqljdbc41.jar或sqljdbc42.jar时的驱动程序 班级图书馆。
所以我尝试删除Class.forName
,然后调用DriverManager.getConnection
。事情正在发挥作用,我不再感到烦人的错误了。
我相信Driver本身必须包含" META-INF / services / java.sql.Driver"将自身注册为有效的JDBC驱动程序的文件,因此不一定适合您,但对于SQL Server驱动程序用户来说,它是可行的。
BTW:我注意到DriverManager.getConnection在第一次调用Drive时需要更多的时间(6或7秒)才能加载Drive。后续调用没问题。根据您的应用程序,这可能是一个问题。
答案 2 :(得分:0)
Class.forName("com.mysql.jdbc.Driver")
将在DriverManager中注册JDBC驱动程序。然后将 hive connection uri 放在
中DriverManager.getConnection(mysqlAddress, username, password)
在这种情况下,预计会出现例外情况。
在检查 uri 之后,为什么不将调用委派给特定的JDBC驱动程序:
if (uri.contains("hive")){
//call Hive JDBC
}
else if (uri.contains("mysql")){
//call Mysql JDBC
}