I have a project in which i connect to my Local Network DB. I Insert,Update and Select from DB, and DB type is SQL Server 2005.
I made a class named ConnectionHelper and everywhere i want to connect to DB, i make an Instance of it and then call its getConnection Method.
This class has a Constructor like this :
public ConnectionHelper() {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
setConnection(connection);
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
setIpAddress("X.X.X.X:1433");
setDb("XXX");
setUserName("XX");
setPassword("XXXX");
setConnectionURL("jdbc:jtds:sqlserver://" + getIpAddress() + ";"
+ "databaseName=" + getDb() + ";user=" + getUserName()
+ ";password=" + getPassword() + ";");
setConnection(DriverManager.getConnection(getConnectionURL()));
} catch (SQLException se) {
Log.e("ERRO", se.getMessage());
} catch (ClassNotFoundException e) {
Log.e("ERRO", e.getMessage());
} catch (Exception e) {
Log.e("ERRO", e.getMessage());
}
}
And this is getConnection Method :
public Connection getConnection() {
return connection;
}
And here is the sample of using this with Callable Statement( Call an Update Stored Procedure) :
ConnectionHelper connectionHelper = new ConnectionHelper();
CallableStatement callableStatement;
try {
callableStatement = connectionHelper.getConnection().prepareCall("{call MySP(?, ?, ?)}");
callableStatement.setInt(1, X);
callableStatement.setInt(2, X));
callableStatement.setInt(3, X);
callableStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
Well, it works good, But Android Devices connect to Local Network via WIFI, and sometimes they could not connect to DB due to Network Problems and then App close it by itself with unfortunately Error.
I want to handle if it could not connect to DB, retry again or display an Toast message to user and do not close the App.
How can i should handle the Exception?
I think you are already catching an exception - but SQLException - so you might find that the exception for connection issue is a Timeout or some other. In this case you need to change the part of your code into something like this:
ConnectionHelper connectionHelper = new ConnectionHelper();
CallableStatement callableStatement;
try {
callableStatement = connectionHelper.getConnection().prepareCall("{call MySP(?, ?, ?)}");
callableStatement.setInt(1, X);
callableStatement.setInt(2, X));
callableStatement.setInt(3, X);
callableStatement.executeUpdate();
} catch (SQLException e) {
//this is a specific SQL exception
e.printStackTrace();
}
catch (Exception e) {
//all other exceptions except the one above
//here you do your toast message
}
Catching the general Exception is good when you do not know all possible exceptions that could be thrown. Please give it a try and let us know if this helps.
Looks like you need an architecture that includes a "internal error" response to the nodes calling your services.
Must not catch the exception in the device, use web api's or webservices to comunicate with DBs.
Now, if your problem is error while processing because the local network on android is down plase look: How to check internet conection on android
Related
I deployed some apps in weblogic server. Few days ago, I traced logs and saw the error message:
2016-09-22 12:58:33,442 ERROR CommonService - ------- ERROR --------- java.sql.SQLException: Internal error: Cannot obtain XAConnection weblogic.common.resourcepool.ResourceDisabledException: Pool jdbc/*** is Suspended, cannot allocate resources to applications..
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResourceInternal(ResourcePoolImpl.java:377)
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:342)
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:329)
at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:417)
at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:324)
at weblogic.jdbc.common.internal.ConnectionPoolManager.reserve(ConnectionPoolManager.java:94)
at weblogic.jdbc.common.internal.ConnectionPoolManager.reserve(ConnectionPoolManager.java:63)
at weblogic.jdbc.jta.DataSource.getXAConnectionFromPool(DataSource.java:1677)
at weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1475)
at weblogic.jdbc.jta.DataSource.getConnection(DataSource.java:446)
at weblogic.jdbc.jta.DataSource.connect(DataSource.java:403)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:364)
at [my-package].ConnectionHandler.newDatabaseConnection(ConnectionHandler.java:37)
I think that having a app leeks connections and doesn't return them to the pool
At temporary solution, I have to extended the the connection pool.
I try to research which apps made this problem and see that some strange codes below:
public class ConnectionHandler
{
..
public ConnectionHandler()
{
logger.trace("ConnectionHandler() constructor called");
}
static Connection newDatabaseConnection() throws SQLException
{
Connection conn;
try {
Context initContext = new InitialContext();
DataSource dataSource = (DataSource) initContext.lookup(LOOKUP_URL);
conn = dataSource.getConnection();
conn.setAutoCommit(false);
} catch (NamingException e) {
logger.error("------- ERROR ---------", e);
throw new ProcessingError("Could not obtain database connection!");
}
return conn;
}
}
This app (SOAP service) will using the code below to query data once having requests:
if (connectionHandler == null) {
connectionHandler = new ConnectionHandler();
}
try {
conn = connectionHandler.newDatabaseConnection();
// Some callable statements here
conn.commit();
logger.info("------- OK ---------");
} catch (SQLException e) {
logger.error("------- ERROR ---------", e);
} catch (InstantiationException e) {
logger.error("------- ERROR ---------", e);
} catch (IllegalAccessException e) {
logger.error("------- ERROR ---------", e);
} catch (DossierServiceException e) {
logger.error("------- ERROR ---------", e);
} finally {
jdbc.close(conn);
}
My confusions which I do not understand yet:
Using the static connection in multi threads is ok?
Create new class (ConnectionHandler) for each request and then get static connection?
Just close the connection without closing the ResultSet, Callable statements?
Could you help me explanation for these ones or having some solutions else to prevent this problem?
The method is static not the result it's returning. static method means that it's not necessary to have an instance of the enclosing class to call it
Yes, that's a mistake, but, not such a big deal
Yes, it would be better first to close the result set, statement and the connection, but this should do the job
The problem with this code is that there's no conn.rollback() in catch blocks and there may be uncaught runtime exceptions that will not be rolled back
My application uses a Mysql connection, which is obtained using this code:
public static void Connect(){
try
{
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url = "jdbc:mysql://" + host + ":" + port + "/"+ db;
ct = DriverManager.getConnection(url, user, pass);
st = ct.createStatement();
System.out.println("Csatlakozva....\n");
}
catch (InstantiationException e)
{
Main.textArea.setText("Error : Instantiation!");
//System.err.println("Error : Instantiation");
e.printStackTrace();
}
catch (IllegalAccessException e)
{
Main.textArea.setText("Error : Illegális Behatolás!");
//System.err.println("Error : Illegális Behatolás!");
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
Main.textArea.setText("Error : Class Nem Található!");
//System.err.println("Error : Class Nem Található!");
e.printStackTrace();
}
catch (SQLException e)
{
Main.textArea.setText("Error : Adatbázis Nem Található!");
//System.err.println("Error : Adatbázis Nem Található!");
e.printStackTrace();
}
}
If the MySQL database server is not running and therefore my app cannot open a connection, how do I make my app wait until a connection can be established?
In order to have your Connect method not return until a connection was actually obtained, you need to surround your existing try-block with a loop. Something like this:
public static void Connect() throws InterruptedException { // It isn't nice to block forever, so we will allow for interrupt
for (;;) {
try
{
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url = "jdbc:mysql://" + host + ":" + port + "/"+ db;
ct = DriverManager.getConnection(url, user, pass);
st = ct.createStatement();
System.out.println("Csatlakozva....\n");
return; // Break out of loop because we got a connection - no exception was thrown
} ...
// One of the exceptions happened. We will continue to loop so
// we try to connect again until we are successful. We don't want
// to retry too fast, because painful experience has taught us that
// bad things can happen (full logs, 100% CPU, etc.).
Thread.sleep(1);
}
}
Exploring and understanding these sorts of low-level issues is a good exercise. However, I will just make a note here that (in my experience) most applications use a connection pool to manage database connections. Generally speaking, the connection pool would provide the functionality of blocking (usually for a limited time) until a connection can be obtained. In other words, the connection pool not only allows for reuse of previously-created connections, but also deal with connection retries when necessary.
I guess you have thread issue.
you can put the JDBC connection code to new thread
private class JDBCConnection extends Thread{
public void run(){
....
}
}
There are many similar questions but I am closing the connection in the finally block. I am testing so I am refreshing the same page often.
in the DAO ( which is called from the controller when the view is accessed)
try {
con= DB.getConnection();
st= connection.createStatement();
rs = statement.executeQuery(MY_QUERY);
while (rs.next()) {
...
}
} catch (SQLException e ) {
e.printStackTrace();
} finally {
try { rs.close(); } catch (Exception e) { /* ignored */ }
try { st.close(); } catch (Exception e) { /* ignored */ }
try { conn.close(); } catch (Exception e) { /* ignored */ }
}
in application.conf
db.default.driver=org.postgresql.Driver
db.default.url="jdbc:postgresql://hostname2/schema"
db.default.user="myuser"
db.default.password="mypass"
Inevitably after a few hours coding I hit the no more connections error. shouldn't the finally close the connection and return it to myuser's pool? Does hitting CTRL-D not close the connection?
Using: PostgreSQL, Java with Play2 framework, running with play run (testing/building stage)
UPDATE: still looking for a reason
Here's some working database code from a project I'm working on:
try
{
//Run a query.
statement = connection.createStatement();
statement.execute(db_request);
results = statement.getResultSet();
//Put the list of names into the table.
table = getTableResults(results);
if(table == null)
return null;
System.out.println("Running database command: " + db_request);
//End.
results.close();
statement.close();
connection.close();
}
catch (SQLException ex)
{
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
return null;
}
return table;
I run all the close statements at the end of the try block and only catch SQLException. If anything else is going on, the console prints the stack trace and shows me the exact line where it broke.
By the way, catch(Exception e) is a REALLY bad coding practice that causes Java to hide errors from you unless they're fatal. I imagine you'd get a lot more information from the stack trace that's automatically printed to the console if you removed those lines.
Seeing how Play Framework gives you play.Logger class, you could instrument that finally and the try {} catch {} inside it with
Logger.info("Something happened...");
and start getting the idea of whats happening for yourself. From top of my head - nothing looks wrong with your code. Do you know the max number of concurrent connections that your db supports btw? If its running in the cloud, there may be an artificial limitation as well.
I'm new to STRUTS and JDBC, my application tries to connect to a simple DB that has 3 tables, right now all is doing is trying to query 1 table that only stores "first, last names and a Id field"
System.out.println("-------- Oracle JDBC Connection Testing ------");
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
System.out.println("Where is your Oracle JDBC Driver?");
e.printStackTrace();
return null;
}
System.out.println("Oracle JDBC Driver Registered!");
try {
connection =
DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe","david","changeit");
} catch (SQLException e) {
System.out.println("Connection Failed! Check output console");
e.printStackTrace();
return null;
}
if (connection != null) {
System.out.println("You made it, take control your database now!");
} else {
System.out.println("Failed to make connection!");
}
where I would like to get the result of 1 column if a match occurs:
String sql = "SELECT S_ID FROM Students WHERE firstname=? AND lastname=?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, firstname);
ps.setString(2, lastname);
rs = ps.executeQuery();
while (rs.next()) {
studentid = rs.getString(1);
ret = SUCCESS;
}
} catch (Exception e) { ...
As far as I can tell the connection is made,
the SQL query
Select s_id from Students where firstname='first' and lastname='last';
when run on SQL Dev. works and gives me a single result.
I don't really get a stack trace the code just jumps from right before the 'while (rs.next()) {..' directly into the finally block
} catch (Exception e) {
e.printStackTrace();
ret = ERROR;
} finally {
if (connection != null) {
try {
connection.close();
} catch (Exception e) {
}
}
}
I'm not sure how Oracle drivers work. But below statement is what i see on Oracle site. Are you getting a non empty resultset ?
As you are not getting a nullpointerexception on .next(), i'm wondering if Oracle drivers return an empty ResultSet, which may lead to this problem.
http://docs.oracle.com/cd/B28359_01/java.111/b31224/getsta.htm
In case of a standard JDBC driver, if the SQL string being executed
does not return a ResultSet object, then the executeQuery method
throws a SQLException exception. In case of an Oracle JDBC driver, the
executeQuery method does not throw a SQLException exception even if
the SQL string being executed does not return a ResultSet object.
Like I said I'm new at using this.
The problem was that my schema didn't have the CONNECT role assigned to it.
Solution log in as 'SYSTEM' and grant the role to my schema
grant connect to MY_SCHEMA;
I have an application that requires a connection to a MS SQL Server 2008 database. Now I have the jdbc driver and I have been struggling to get it to connect successfully. This is my connection code:
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
int duration = Toast.LENGTH_SHORT;
Connection con = DriverManager.getConnection(jdbc:jtds:sqlserver://41.76.209.156:1433; databaseName=prooptin_ProOptData", "username", "password");
textview7.setText(con.toString());
textview7.setText("Successful");
} catch (ClassNotFoundException e) {
textview7.setText("Could not find the database driver " + e.getMessage());
} catch (SQLException e) {
textview7.setText("Could not connect to the database " + e.getMessage());
} catch (Exception e) {
textview7.setText(e.getMessage());
}
It seems to hang at the DriverManager.getConnection() line. I have tried to alter the connection string, and tried it with and without the username and password and database name, and nothing will work. It does not print an exception message, just returns a blank message and nothing happens.