java.sql.SQLException: General error - java

Getting java.sql.SQLException
java.sql.SQLException: General error
at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6986)
at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7114)
at sun.jdbc.odbc.JdbcOdbc.SQLExecDirect(JdbcOdbc.java:3110)
at sun.jdbc.odbc.JdbcOdbcStatement.execute(JdbcOdbcStatement.java:338)
at sun.jdbc.odbc.JdbcOdbcStatement.executeQuery(JdbcOdbcStatement.java:253)
at com.test.Temp.main(Temp.java:29)
I am using following code
Connection con=null;
ResultSet rs=null;
Statement stmt=null;
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con=DriverManager.getConnection("jdbc:odbc:locator","locator","locator");
stmt=con.createStatement();
System.out.println("Before query");
String query=null;
query="select * from user_location_table";
System.out.println("after query12");
rs=stmt.executeQuery(query);
//perform certain operation....
rs.close();
stmt.close();
con.close();
} catch(Exception e) {
e.printStackTrace();
}
The exception is thrown at stmt.executeQuery(query).
user_location_table contains following fields
user_id:number not null,
latitude:number,
longitude:number,
update_time:timestamp(6)
Thanks in advance

I get it.
The error is thrown due to the use of datatype timestamp(6) in update_time.The exception is thrown whenever we try to execute the select statement containing a column with timestamp as the datatype.
Instead of the previous code we can use the following code for selecting
query="select latitude,longitude,to_char(update_time,'HH24:MI:SS'),to_char(update,time,'DD-MON-YY') from user_location_table";
This works fine,I have tested it.
Cheers!!

A couple of thoughts. If it's only happening on the first execute, it may be that there is something invalid in the db and it's being compiled. Secondly, you may have something leaking because you aren't closing your connection and statement in a finally block. So if you get an exception, you aren't closing the connections and potentially you're creating a lock on your DB.
Add a finally block and move your close statements there checking for null:
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con=DriverManager.getConnection("jdbc:odbc:locator","locator","locator");
stmt=con.createStatement();
System.out.println("Before query");
String query=null;
query="select * from user_location_table";
System.out.println("after query12");
rs=stmt.executeQuery(query);
//perform certain operation....
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
if (rs!=null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (stm!=null)
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (con!=null)
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}

Related

Try with resources Statement for JDBC in java

Useful piece of code for Hive JDBC:
Connection con = null;
Statement stmt = null
try {
Class.forName("org.apache.hive.jdbc.HiveDriver");
con = DriverManager.getConnection(connectionUri, userName, password);
stmt = con.createStatement();
stmt.executeUpdate(query);
} catch (ClassNotFoundException cex) {
cex.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
I want to remove try - catch in finally block.
So I tried The try-with-resources Statement.
try (Class.forName("org.apache.hive.jdbc.HiveDriver");
Connection con = DriverManager.getConnection(connectionUri, userName, password);
Statement stmt = con.createStatement();){
stmt.executeUpdate(query);
} catch (ClassNotFoundException cex) {
cex.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
I think this is not the right way.
Class.forName("org.apache.hive.jdbc.HiveDriver") should not be in try. Should I make a separate try-catch for this?
try {
Class.forName("org.apache.hive.jdbc.HiveDriver");
} catch (ClassNotFoundException cex) {
cex.printStackTrace();
}
try (Connection con = DriverManager.getConnection(connectionUri, userName, password);
Statement stmt = con.createStatement();){
stmt.executeUpdate(query);
} catch (SQLException e) {
e.printStackTrace();
}
Is this right way or am I missing any thing?
The idea behind try-with-ressource is to close an AutoCloseable class.
So every usage of a class which should be closed after using it (a Ressource) can be used with try-with-ressource (like Connection for example). You don't have to take care of closing it manually (in an finally block for example).
So yes, your idea is right:
try/catch for Class.forName("org.apache.hive.jdbc.HiveDriver"); - because this is not AutoCloseable
try-with-ressource for Connection con = DriverManager.getConnection(connectionUri, userName, password);
Statement stmt = con.createStatement();- because Connection and Statement implement AutoCloseable
Reference:
https://docs.oracle.com/javase/7/docs/api/java/lang/AutoCloseable.html
When you're using Java 6 or better and the Apache Hive JDBC driver is JDBC 4 compliant or better* then you do not need the Class.forName("org.apache.hive.jdbc.HiveDriver") stuff at all.
Therefore you can just remove the entire try/catch block from your second solution and you're good to go with just:
try (Connection con = DriverManager.getConnection(connectionUri, userName, password);
Statement stmt = con.createStatement()) {
stmt.executeUpdate(query);
} catch (SQLException e) {
e.printStackTrace();
}
* Which is the case for version 1.2.0 or newer of the Hive JDBC driver

rollback mysql transcations from multiplate methods GWT

I'm trying to figure out how to rollback commits from multiple methods. I want to do something like the following (editing for brevity)
public void testMultipleMethodRollback() throws DatabaseException {
Connection conn = connect();
fakeMethodRollback1();
fakeMethodRollback2();
try {
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
and currently all my methods are formatted like this
public void fakeMethodRollback1() throws DatabaseException {
Connection con = connect();
PreparedStatement ps = null;
ResultSet rs = null;
// insert some queries
try {
String query = "some query";
ps = conn.prepareStatement(query);
ps.executeUpdate(query);
query = "some query";
ps = conn.prepareStatement(query);
ps.executeUpdate(query);
con.commit();
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
throw new DatabaseException(e);
} finally {
close(rs, ps, conn);
}
}
because I want to be able to use the other methods independently, how can I do a rollback where if one method fails, the others will roll back? I fear I have my whole class setup wrong or at least wrong enough that this can't be accomplished without major work. I can't change the methods to return a connection, because half of my methods are get methods, which are already returning other data. Any ideas?

java.sql.SQLException: Invalid state, the CallableStatement object is closed

The code below generates this exception:
java.sql.SQLException: Invalid state, the CallableStatement object is closed.
at net.sourceforge.jtds.jdbc.JtdsCallableStatement.checkOpen(JtdsCallableStatement.java:120)
at net.sourceforge.jtds.jdbc.JtdsStatement.getConnection(JtdsStatement.java:1207)
at net.sourceforge.jtds.jdbc.JtdsResultSet.getConnection(JtdsResultSet.java:409)
at net.sourceforge.jtds.jdbc.JtdsResultSet.close(JtdsResultSet.java:470)
at org.apache.tomcat.dbcp.dbcp.DelegatingResultSet.close(DelegatingResultSet.java:152)
at
This code below sometimes generates the error above, but sometimes does not:
private void doRequest(HttpServletRequest request) throws IOException, ServletException {
CallableStatement stmt = null;
ResultSet rs = null;
String someString;
try {
this.connectDB();
stmt = this.conn.prepareCall("{call sp_SomeSP1(?)}");
stmt.setLong(1, someFunc());
rs = stmt.executeQuery();
while (rs.next()) {
if (rs.getInt(1)==someOtherFunc()) {
someString = rs.getString(2);
break;
}
}
stmt = conn.prepareCall("{call sp_someSP(?, ?)}");
stmt.setLong(1, someFunc());
stmt.setTimestamp(2, new Timestamp(getFrom().getTime()));
rs = stmt.executeQuery();
if (rs.next()) {
lastUpdated = rs.getTimestamp("LastUpdated");
}
request.setAttribute("lastUpdated", lastUpdated);
LOGGER.debug("Forwarding to view...");
getServletContext().getRequestDispatcher("/SomeJSP.jsp").forward(this.request, this.response);
} catch (NamingException e) {
LOGGER.error("Database connection lookup failed", e);
sendError("Server Error");
} catch (SQLException e) {
LOGGER.error("Query failed", e);
sendError("Server Error");
} catch (IllegalStateException e) {
LOGGER.error("View failed", e);
} finally {
try {
if (rs!=null) rs.close();
} catch (NullPointerException e) {
LOGGER.error("Result set closing failed", e);
} catch (SQLException e) {
LOGGER.error("Result set closing failed", e);
}
try {
if (stmt!=null) stmt.close();
} catch (NullPointerException e) {
LOGGER.error("Statement closing failed", e);
} catch (SQLException e) {
LOGGER.error("Statement closing failed", e);
}
try {
this.closeDB();
} catch (NullPointerException e) {
LOGGER.error("Database connection closing failed", e);
} catch (SQLException e) {
LOGGER.error("Database connection closing failed", e);
}
}
What this means is that doRequest() most of the time works properly, but sometimes we get HTTP error 500, and if we check tomcat logs we see:
java.sql.SQLException: Invalid state, the CallableStatement object is closed.
You seem to be using a member variable with a Servlet (the conn variable). however, Servlets can normally be called by multiple threads simultaneously. how are you ensuring that multiple threads are not accidentally using/closing the same Connection?
stmt.setLong(1, someFunc());
stmt.setTimestamp(3, new Timestamp(getFrom().getTime()));
It will be
stmt.setLong(1, someFunc());
stmt.setTimestamp(2, new Timestamp(getFrom().getTime()));
Seeing this error message org.apache.tomcat.dbcp.dbcp.DelegatingResultSet.close in the stack trace, it looks like you are getting error while closing the resultset.
I would advice you to change your resultset check if condition to check whether result set is still open before closing it as:
if (rs!=null && ! rs.isClosed()){
//resultset is there and not in closed state
rs.close();
}

how to handle an exception occured in finally block

In the following code snippet,
try
{
Statement stmt = conect.getConnection();
stmt.executeUpdate(query);
}
catch(SQLException e)
{
//handle exception
}
finally
{
try{ stmt.close(); }
catch(SQLException ignore){}
}
what happens when an exception occurs in the finally block while executing stmt.close();.
Is there a better way to handle these kind of problems?
sometimes connections is not open because of some exception but finally block close that connection. To avoid this Exception check out following code.
try{
Statement stmt = conect.getConnection();
stmt.executeUpdate(query);
}catch(SQLException e){
//handle exception
}finally{
try{
if(stmt != null){
stmt.close();
}
}
catch(SQLException ignore){}
}
finally
{
if( stmt != null ) {
try {
stmt.close();
}
catch(SQLException ex ) {
ex.printStackTrace();
}
}
}
Problems which might occur is that a statement isn't closed and then you will get an error when trying to reuse it.
try:
Statement stmt = null;
try {
stmt = conect.getConnection();
stmt.executeUpdate(query);
}
catch(SQLException e) {
//handle exception
}
finally
{
try{ if(stmt!=null)stmt.close(); }
catch(SQLException ignore){}
}
Usually when an exception occur we wrap it over our User defined exception and throw.
Similarly u need to throw ur own exception, when an exception occurs in finally also.
try
{
Statement stmt = conect.getConnection();
stmt.executeUpdate(query);
}
catch(SQLException e)
{
//handle exception
throw MyOwnException(e,"My message");
}
finally
{
try{ stmt.close(); }
catch(SQLException ignore)
{
throw MyOwnException(ignore,"My message");
}
}

Is that the best way to release SQLite connection in Java?

I need a good way to close SQLIte connections in Java. After a few suggestion by other users I decided to add to my code a finally block to be sure that closing operation are always executed.
public static boolean executeQuery(String query)
{
Connection conn = null;
Statement stmt = null;
try
{
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection(Global.dbPath);
stmt = conn.createStatement();
stmt.execute(query);
return true;
}
catch(ClassNotFoundException e)
{
System.out.println(e);
return false;
}
catch(SQLException e)
{
System.out.println(e);
return false;
}
finally
{
try
{
stmt.close();
conn.close();
return true;
}
catch (SQLException ex)
{
System.out.println ("Errore closing connections");
return false;
}
}
}
I'm not sure that this is the best solution.
How can I optimize this for readability?
A few comments; nutshells:
Separate the SQL exceptions from the reflection exception.
Are your SQL exceptions recoverable? If not, throw an app-specific RuntimeException.
Wrap up the connection and statement close exceptions in a utility method, yours or a 3rd party's.
Don't short-change exception handling; dump the stack trace.
This leads to the following:
public static boolean executeQuery(String query) {
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e) {
throw new DbException("Could not find JDBC driver", e);
}
Connection conn = null;
Statement stmt = null;
try {
conn = DriverManager.getConnection(Global.dbPath);
stmt = conn.createStatement();
stmt.execute(query);
return true;
} catch(SQLException e) {
throw new DbException("Exception during statement execution", e);
} finally {
DbUtils.closeQuietly(conn);
DbUtils.closeQuietly(stmt);
}
}
(I'm using Apache Commons' DbUtils for its closeQuietly, it checks for null (yours didn't). Your own version might throw an app-specific exception as I do here with DbException. This wraps up all your DB-related exceptions into a single exception class, which may or may not be what you need.
If you want to make sure a command is executed you have to put it alone into a try catch block:
try {
stmt.close();
}
catch (Exception ex) {
}
try {
conn.close();
}
catch (Exception ex) {
System.out.println ("Error closing connections");
return false;
}

Categories