Using both Hive and MySql JDBC drivers - mysql

TL;DR:
Is it problematic to use both Hive and MySql JDBC together?
I'm working on an application that performs several SQL queries using the MySql JDBC driver and afterwards it also send another Hive query using Hive JDBC.
Now whats happening is that the MySql queries are working properly, when the code tries to execute the Hive query it throws this exception:
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)
Now after this exception is thrown the query is executed properly.
My guess is that since I'm loading both the MySql and Hive drivers, the MySql driver is trying to run this query first but when it encounters the Hive URL it throws this exception and then the Hive driver sees it and executes the query properly
This is how I execute the MySql code:
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()
}
}
My Hive code looks the same only with a driver name of: org.apache.hive.jdbc.HiveDriver (and it communicates with jdbc:hive2://someurl)
Versions:
Hive is hive-jdbc-1.1.0-cdh5.7.1
MySql is mysql-connector-java 6.0.4
Does anybody know if there's any way to avoid receiving this exception? Is it problematic to load 2 different JDBC drivers? Reading in other somewhat similar questions I get the impression that this should not be a problem
Just a few clarifications:
I know its probably not the best thing to use JDBC directly but I'm checking something and JDBC is fine for this task
I'm using Scala but I don't think it matters for this issue
Thanks in advance

I almost forgot to answer my question
So the issue is probably related to this bug. Back when I was facing this issue I didn't notice it was just a stack trace print and not an actual failure so it was less problematic than I expected.
Anyway, I then saw that in some specific versions this issue was fixed as you can see here so I just changed my mysql version to 5.1.9 (because I didn't need the higher version for anything specific) and the stack trace failure was gone.
I'll be happy if to hear if someone has a more elegant solution to this
Cheers

I was facing the same issue with MS SQL Server JDBC Driver. The same error was logged but everything worked fine.
According to this Microsoft page:
In the JDBC API 4.0, the DriverManager.getConnection method is
enhanced to load JDBC drivers automatically. Therefore, applications
do not need to call the Class.forName method to register or load the
driver when using the sqljdbc4.jar, sqljdbc41.jar, or sqljdbc42.jar
class library.
So I tried removing the Class.forName and just called DriverManager.getConnection. Things are just working and I'm not getting the annoying error anymore.
I believe the Driver itself must include a "META-INF/services/java.sql.Driver" file that registers itself as a valid JDBC driver, so not necessarily it will work for you, but to SQL Server Driver users it's the way to go.
BTW: I noticed that DriverManager.getConnection takes significant more time (6 or 7 seconds) to load the Drive the first time it's called. Subsequent calls are OK. Depending on your application it may be an issue.

Class.forName("com.mysql.jdbc.Driver")
will register your JDBC driver in the DriverManager. Then you put hive connection uri in
DriverManager.getConnection(mysqlAddress, username, password)
Exception is expected in this case.
Why don't you delegate the call to particular JDBC driver after checking uri like:
if (uri.contains("hive")){
//call Hive JDBC
}
else if (uri.contains("mysql")){
//call Mysql JDBC
}

Related

Postgres vs MySQL: Commands out of sync;

MySQL scenario:
When I execute "SELECT" queries in MySQL using multiple threads I get the following message: "Commands out of sync; you can't run this command now", I found that this is due to the limitation of having to wait "consume" the results to make another query. C ++ example:
void DataProcAsyncWorker::Execute()
{
std::thread (&DataProcAsyncWorker::Run, this).join();
}
void DataProcAsyncWorker :: Run () {
sql::PreparedStatement * prep_stmt = c->con->prepareStatement(query);
...
}
Important:
I can't help using multiple threads per query (SELECT, INSERT, ETC) because the module I'm building that is being integrated with NodeJS "locks" the thread until the result is already obtained, for this reason I need to run in the background (new thread) and resolve the "promise" containing the result obtained from MySQL
Important:
I am saving several "connections" [example: 10], and with each SQL call the function chooses a connection. This is: 1. A connection pool that contains 10 established connections, Ex:
for (int i = 0; i <10; i ++) {
Com * c = new Com;
c->id = i;
c->con = openConnection ();
c->con->setSchema("gateway");
conns.push_back(c);
}
The problem occurs when executing> = 100 SELECT queries per second, I believe that even with the connection balance 100 connections per second is a high number and the connection "ex: conns.at(10)" is in process and was not consumed
My question:
Does PostgreSQL have this limitation as well? Or in PostgreSQL there is also such a limitation?
Note:
In PHP Docs about MySQL, the mysqli_free_result command is required after using mysqli_query, if not, I will get a "Commands out of sync" error, in contrast to the PostgreSQL documentation, the pg_free_result command is completely optional after using pg_query.
That said, someone using PostgreSQL has already faced problems related to "commands are out of sync", maybe there is another name for this error?
Or is PostgreSQL able to deal with this problem automatically for this reason the free_result is being called invisibly by the server without causing me this error?
You need to finish using one prepared statement (or cursor or similar construct) before starting another.
"Commands out of sync" is often cured by adding the closing statement.
"Question:
Does PostgreSQL have this limitation as well? Or in PostgreSQL there is also such a limitation?"
No, the PostgreSQL does not have this limitation.

XPages JDBC connected to MS ACCESS DB, issue showing data in ViewPanel

I am trying to connect XPagesJDBC.nsf to a simple MS Access database,
it connects Successfully and i am able to perform the #JdbcInsert , Update, Delete. also able to execute SQL Query operations.
But i am facing an issue while trying to showing data in ViewPanel control with JDBC Query datasource type.
It give bellow error
Error while reading the relational data
Invalid Fetch Size
and a long StackTrace, i am copying some part of stack trace bellow;
I think this error is specific to MS Access, because i could find some successful implementation with other RDBMS also it work fine with "durby" at my end.
com.ibm.xsp.util.FacesUtil.renderComponent(FacesUtil.java:840)
com.ibm.xsp.util.FacesUtil.renderComponent(FacesUtil.java:851)
com.ibm.xsp.util.FacesUtil.renderComponent(FacesUtil.java:851)
com.ibm.xsp.util.FacesUtil.renderComponent(FacesUtil.java:851)
com.ibm.xsp.util.FacesUtil.renderComponent(FacesUtil.java:851)
com.ibm.xsp.component.UIViewRootEx._renderView(UIViewRootEx.java:1317)
com.ibm.xsp.component.UIViewRootEx.renderView(UIViewRootEx.java:1255)
com.ibm.xsp.application.ViewHandlerExImpl.doRender(ViewHandlerExImpl.java:641)
com.ibm.xsp.application.ViewHandlerExImpl._renderView(ViewHandlerExImpl.java:320)
com.ibm.xsp.application.ViewHandlerExImpl.renderView(ViewHandlerExImpl.java:335)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:103)
com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:210)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:120)
com.ibm.xsp.controller.FacesControllerImpl.render(FacesControllerImpl.java:264)
com.ibm.xsp.webapp.FacesServlet.serviceView(FacesServlet.java:248)
com.ibm.xsp.webapp.FacesServletEx.serviceView(FacesServletEx.java:200)
com.ibm.xsp.webapp.FacesServlet.service(FacesServlet.java:160)
com.ibm.xsp.webapp.FacesServletEx.service(FacesServletEx.java:137)
com.ibm.xsp.webapp.DesignerFacesServlet.service(DesignerFacesServlet.java:103)
com.ibm.designer.runtime.domino.adapter.ComponentModule.invokeServlet(ComponentModule.java:576)
com.ibm.domino.xsp.module.nsf.NSFComponentModule.invokeServlet(NSFComponentModule.java:1267)
com.ibm.designer.runtime.domino.adapter.ComponentModule$AdapterInvoker.invokeServlet(ComponentModule.java:847)
com.ibm.designer.runtime.domino.adapter.ComponentModule$ServletInvoker.doService(ComponentModule.java:796)
com.ibm.designer.runtime.domino.adapter.ComponentModule.doService(ComponentModule.java:565)
com.ibm.domino.xsp.module.nsf.NSFComponentModule.doService(NSFComponentModule.java:1251)
com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:598)
com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:421)
com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:341)
com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:297)
com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:272)
java.sql.SQLException: Invalid Fetch Size
sun.jdbc.odbc.JdbcOdbcStatement.setFetchSize(JdbcOdbcStatement.java:838)
sun.jdbc.odbc.JdbcOdbcResultSet.setFetchSize(JdbcOdbcResultSet.java:2987)
com.ibm.xsp.extlib.jdbc.model.JdbcDataBlockAccessor.loadBlock(JdbcDataBlockAccessor.java:389)
com.ibm.xsp.extlib.model.DataBlockAccessor.findBlockByIndex(DataBlockAccessor.java:344)
com.ibm.xsp.extlib.model.DataBlockAccessor.prefetchData(DataBlockAccessor.java:292)
com.ibm.xsp.extlib.model.DataAccessorModel.getRowCount(DataAccessorModel.java:93)
com.ibm.xsp.component.UIPager$PagerState.<init>(UIPager.java:76)
com.ibm.xsp.component.UIPager$PagerState.<init>(UIPager.java:71)
com.ibm.xsp.component.UIPager.createPagerState(UIPager.java:540)
com.ibm.xsp.renderkit.html_extended.XPagerRenderer.encodeChildren(XPagerRenderer.java:67)
com.ibm.xsp.renderkit.ReadOnlyAdapterRenderer.encodeChildren(ReadOnlyAdapterRenderer.java:162)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:979)
com.ibm.xsp.util.FacesUtil.renderComponent(FacesUtil.java:842)
com.ibm.xsp.renderkit.html_extended.ViewPanelRenderer.processPagerCell(ViewPanelRenderer.java:656)
com.ibm.xsp.renderkit.html_extended.ViewPanelRenderer.encodeBegin(ViewPanelRenderer.java:354)
com.ibm.xsp.renderkit.ReadOnlyAdapterRenderer.encodeBegin(ReadOnlyAdapterRenderer.java:146)
javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:956)
javax.faces.component.UIData.encodeBegin(UIData.java:788)
com.ibm.xsp.component.UIDataEx.encodeBegin(UIDataEx.java:413)
com.ibm.xsp.component.UIViewPanel.encodeBegin(UIViewPanel.java:288)
com.ibm.xsp.util.FacesUtil.renderComponent(FacesUtil.java:840)
com.ibm.xsp.util.FacesUtil.renderComponent(FacesUtil.java:851)
com.ibm.xsp.util.FacesUtil.renderComponent(FacesUtil.java:851)
myconnection.jdbc file ; ext_db is a DSN
<jdbc>
<driver>sun.jdbc.odbc.JdbcOdbcDriver</driver>
<url>jdbc:odbc:ext_db</url>
<user>xxx</user>
<password>xxx</password>
</jdbc>
The tongue-in-cheek-answer: get a database :-)
The problem seems to be well known and plagues others too to quite some extend. The batch-size parameter (first link) might work. You also could revisit your requirements. Would DECS do the trick?

SQL Server 2008 - Crash when opening recordset

I have to do some maintenance on a software that was delivered to a customer.
This software is using database and in order to do some debugging session on my computer, I had to install SQL server 2008 R2 and the two database (MyData and MyRecord) that are used by this software.
I had some troubles doing the setting (login, mapping of the database to sa user) but I managed to go over those issues.
Now I am trying to run the software but it crashes during initialization when it tries to open a recordset.
At first I do the following to connect to the database :
::CoInitialize(NULL);
try
{
HRESULT hr = pConnection.CreateInstance("ADODB.Connection");
if (SUCCEEDED(hr))
{
pConnection->ConnectionTimeout = 0;
CString strConnect;
strConnect.Format(_T("Data Source=MyRecord;uid=sa;pwd=sa123456;"));
hr = pConnection->Open((_bstr_t)strConnect,"","", -1);
}
}
with pConnection defined as :
_ConnectionPtr pConnection;
After that, I am trying to read some data from the database "MyRecord" with the following code :
CString sqlQuery = _T("select * from 通道1设置参数表");
try
{
pRecordset.CreateInstance(_uuidof(Recordset));
pRecordset->Open(_bstr_t(sqlQuery ),pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
}
catch(_com_error *e)
{
AfxMessageBox(e->Description());
}
with pRecordSet defined as :
_RecordsetPtr pRecordset;
When the line "pRecordset->Open(...)" is run, the software crashes in the function Recordset15::Open(...) of the msado15.tli file.
In this Recordset15::Open function, the raw_Open(...) function returns DB_E_NOTABLE.
However, I am sure that the table dbo.通道1设置参数表 exists in MyRecord database.
The error is :
I don't know if the problem lies in the SQL server configuration or in the code.
This code works perfectly well on the customer's PC so I would go with a configuration problem.
Thanks in advance !!
In the ODBC connector for this database, the setting "Change the default database to" was not set to the MyRecord database.
I have ticked the check-box, selected the database and now it is working correctly.
Your catch statement should be catch(_com_error & e)
MFC often throws exceptions by pointers, however _com_error is a reference.

Linq with MySQL database in ASP.NET MVC 3, storing DateTime into variable

I am using MySQL database to work in ASP.NET MVC 3, i've already set up all requirements and connection is working fine. This code below is working properly and produce right result :
try
{
ViewBag.Model = (from n in _db.mainDatas
where n.time_stamp == new DateTime(2010, 11, 3, 0, 0, 15)
select n).Take(10).ToList();
}catch (Exception e) {
ViewBag.Error = e;
}
But when i change this code into :
DateTime test = new DateTime(2010,11,3,0,0,15);
try
{
ViewBag.Model = (from n in _db.mainDatas
where n.time_stamp == test
select n).Take(10).ToList();
}catch (Exception e) {
ViewBag.Error = e;
}
this error message is generated :
MySql.Data.MySqlClient.MySqlException: Fatal error encountered during command execution. ---> MySql.Data.MySqlClient.MySqlException: Unable to serialize date/time value
I am using MySQL Connector/Net 6.3.6. Any solution to this problem ?
It seems to be a problem with the Linq to SQL provider for MySql that you have been using.
In first case the date part is "in" the Expression tree that is generate from your linq query where as in the second case the DateTime is declared out side of the Linq query and hence the generated expression tree will be different from the first case. Now it depends on the parser of expression tree in the Linq to SQL provider how to handle both the cases and it seems in this case the provider is not able to properly handle the second case expression tree.
Ok, after doing some searches and googling like crazy, finally I found the solution for my problem. Well, it's not a solution actually, because it looks like MySQL Connector/Net 6.3.6 is not doing well with my project (maybe because of my server, database, project configurations, etc) so I use Devart dotConnector instead of MySQL Connector/Net 6.3.6 and everything works like magic. :D

JDBC setQueryTimeout not working?

I'm querying MSSQL 2008 server thourgh JAVA, using the JDBC driver.
I do something like this:
PreparedStatement stmt = ...;
...
stmt.setQueryTimeout(60);
stmt.executeQuery();
I see that when there's a load on the SQL server, the statement doesn't get cancelled even though the timeout has passed.
Does anyone have a clue about this?
Thanks.
The timing for setQueryTimeout is not precise at all
The exception relies on the server acknowledging the cancel command
So, YMMV unfortunately...
References: (can't find anything better, sorry)
http://social.msdn.microsoft.com/Forums/en-US/sqldataaccess/thread/06bea9b9-78cb-4d1b-8c12-5f06ed991cac/
http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-jdbc/1017/setQueryTimeout-not-work