Locally everything works fine, but on a remote Weblogic not really. The next code runs without any exception.
try
{
ods = new OracleDataSource();
connectionString = XmlReader.getConnectionString();
ods.setURL(connectionString);
}
catch (SQLException ex)
{
ex.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
When i call getConnection() on the previous ods object, it doesnt raise any exception
try
{
if (connection == null || connection.isClosed()) {
connection = ods.getConnection();
}
}
catch(Exception e) {
e.printStackTrace();
}
But finally the connection object is null
for example after calling this
CallableStatement cstmt = connection.prepareCall( jobquery );
On a database it looks like the application created the connection, but then it doesnt call the procedure specified in "jobquery". What could be wrong?
Simply my question is: Is there a way to create an OracleDataSource without an exception, and then get a null from it?
Nambaris answer will probably solve your immediate issue. Other points to consider:
On weblogic you really should be using built-in datasources and look those up by JNDI name
Are you sure it doesn't throw an exception, or are you just not seeing it due to printing it out on stderr? You should be using logging mechanism and exception propagation, not printing to outputs.
These are not directly related to your problem, just things you should be doing in the long run.
Unless you miss some code in original question, it seems you didn't perform execute().
Example:
callableStatement.executeQuery();
Read this CallableStatement tutorial
Related
I have a one problem regarding Database(Oracle 10g). I have developed Web Application in JSP Servlet. now I am Performing testing on it. First I have Faced one problem (i.e. "ORA-01000: maximum open cursors exceeded"). For Solving the problem I was closed every connections in every files (eg: Foo.java and Foo.jsp) where the Database connection is established. For this, I have used the Following code:
finally {
if(rs1 != null) {
try {
rs1.close();
} catch (SQLException e) { /* ignored */ }
if(ps2 != null) {
try {
ps2.close();
} catch (SQLException e) { /* ignored */ }
}
if(con != null) {
try {
con.close();
} catch (SQLException e) { /* ignored */ }
}
}
But now the code gives another problem: Application does not fetch any records from database.
When First time I click linked (Add Menu then it shows all data but when I clicked another linked then all records are vanished.
Then after like this.
and Show Error java.sql.SQLException: Closed Connection
May be you have defined the connection object out side of the method,for the first time using the connection object it connects to the database and when you click on the link again the same methods gets invoked and the connection object is already closed in finally and hence could not connect to database again causing closed connection Exception.
First thing is to create the connection or prepared statement or statement inside the method and fetch the result set.When again the method is called the connection object is created again with help of connection pool and hence can make successful connection to data base.
I found this example to connect with a SQLite database:
try{
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:C:\\pruebaSQLite\\dbTest.sqlite");
System.out.println("Conectado a la base de datos SQLite ");
}catch(Exception e){
System.out.println(e);
}
it's working fine but I try to connect a JAVA application using it like this:
try {
Class.forName("org.sqlite.JDBC");
Connection con = DriverManager.getConnection("jdbc:sqlite:C:\\LoginJava2\\myDB.sqlite");
PreparedStatement pstm = con.prepareStatement("insert into hell(username,pssword) " +
"values ('"+tfUname.getText()+"','"+tfUpass.getText()+"')");
pstm.close();
con.close();
JOptionPane.showMessageDialog(null,"Congrats, you have been registered succesfully");
RegisterWindow rw = new RegisterWindow();
rw.setVisible(false);
pack();
dispose();
} catch(SQLException ex) {
setTitle(ex.toString());
}
the line: "Class.forName("org.sqlite.JDBC");" give me the next error:
Unhandled exception type ClassNotFoundException
if I remove that line the program runs fine but when I execute the action, it gives me the next exception:
java.sql.SQLException: No suitable driver found for jdbc:sqlite:C:\\LoginJava2\\myDB.sqlite
That's weird because I'm using the same jar in both examples.
I'm using the next jar file: "sqlitejdbc-v056"
if someone could help me how to fix the error in the "line Class.forName("org.sqlite.JDBC");"
or if I'm doing someting wrong in the URL connection... I will apreciate!!
Thanks and sorry for my english!!
if someone clud help me how to fix the error in the "line Class.forName("org.sqlite.JDBC");" or if I'm doing someting wrong in the URL connection... I will apreciate!!
The error message is telling you exactly what needs to be fixed -- you need to handle the exception that it mentions, the ClassNotFoundException.
The main thing you should notice is that catch blocks in your two code examples are different, and one works while the other doesn't. Note that I don't recommend that you use the first catch block, the one that catches Exception, even though it works, since catching all Exceptions is usually not a good idea and prevents exceptions that should percolate to a higher level from doing so. Instead you should catch the explicit Exceptions that need to be caught, here SQLException and ClassNotFoundException.
The Exception Tutorial should help explain this more fully to you with code examples. How you catch this also will depend on if you're working with Java 1.7 or prior versions.
To Fix the problem I added the next to the code:
try {
Class.forName("org.sqlite.JDBC");
Connection con = DriverManager.getConnection("jdbc:sqlite:C:\\LoginJava2\\myDB.sqlite");
Statement com = con.createStatement();
com.executeUpdate("insert into hell(username,pssword) " +
"values ('"+tfUname.getText()+"','"+tfUpass.getText()+"')");
con.close();
JOptionPane.showMessageDialog(null,"Congrats, you have been registered succesfully");
RegisterWindow rw = new RegisterWindow();
rw.setVisible(false);
pack();
dispose();
} catch(SQLException ex) {
setTitle(ex.toString());
}
catch(ClassNotFoundException e) { // I added this catch to handle the exception
setTitle(e.toString());
}
I have been learning about using MySQL within Java using Oracle JDBC and I am trying to get into the mindset of try/catch and pool cleanup.
I am wondering if the following code is the correct way to perfectly clean everything up or if you notice holes in my code that requires something I've missed. For the record, I intend to use InnoDB and its row locking mechanism which is why I turn auto commit off.
try
{
connection = getConnection(); // obtains Connection from a pool
connection.setAutoCommit(false);
// do mysql stuff here
}
catch(SQLException e)
{
if(connection != null)
{
try
{
connection.rollback(); // undo any changes
}
catch (SQLException e1)
{
this.trace(ExtensionLogLevel.ERROR, e1.getMessage());
}
}
}
finally
{
if(connection != null)
{
try
{
if(!connection.isClosed())
{
connection.close(); // free up Connection so others using the connection pool can make use of this object
}
}
catch (SQLException e)
{
this.trace(ExtensionLogLevel.ERROR, e.getMessage());
}
}
}
getConnection() returns a Connection object from a pool and connection.close() closes it releasing it back to the pool (so I've been told, still new to this so apologies if I am talking rubbish). Any help on any of this would be greatly appreciated!
Thank you!
I recommend not setting autocommit back to true in the finally block - your other threads that are relying on autocommit being set to true should not assume that the connections in the pool are in this state, but instead they should set autocommit to true before using a connection (just as this thread is setting autocommit to false).
In addition, you should check the connection's isClosed property before calling close() on it.
Other than that, I don't see any problems.
I currently am working on a project that does a lot of work with Database.
One core idiom that I have reused many, many times in my code is the following.
My question is, is there a better way to handle the exceptions at each step of the getTransformedResults method? Is this a proper way of handling the SQLExceptions, or is there a better, more concise way of doing this?
Thanks for your input!
public ResultType handleResultSet(ResultSet rs);
public ResultType getTransformedResults(String query) throws SQLException {
ResultType resultObj = new ResultType();
Connection connection = null;
try {
connection = dataSource.getConnection();
} catch (SQLException sqle) {
// cleanup
throw sqle;
}
Statement stmt = null;
try {
stmt = connection.createStatement();
} catch (SQLException sqle) {
try { connection.close() } catch (SQLException dontCare) {}
// cleanup
throw sqle;
}
ResultSet rs = null;
try {
ResultSet rs = stmtm.executeQuery(query);
resultObj = handleResultSet(rs);
} catch (SQLException sqle) {
// cleanup
throw sqle;
} finally {
if (rs != null) try { rs.close() } catch (SQLException dontCare) {}
try { stmt.close() } catch (SQLException dontCare) {}
try { connection.close() } catch (SQLException dontCare) {}
}
return resultObj;
}
Java 7 has some constructs you might appreciate, I think you can use try/finally without catch (which mimics your catch and rethrow).
Also, since you've caught and handled the SQL exception, perhaps you should re-throw it as something else--perhaps as a runtime exception--this makes it easier to catch all runtime exceptions at a primary entry point rather than having to deal with exceptions every single time you access the DB.
Personally I might handle this by passing in an interface implementation rather than subclassing.
Ultimately, if you're only handling the exceptions in that method, and not polluting the mainline code, what else can you really do, and what would be the point of doing it? You might make each step a bit more granular so it's not all in one method, but other than that...
You might consider an application-specific exception, which may make testing and configuration cleaner, but that depends on context.
Clarification of interface idea
Instead of subclassing you'd have an interface that implemented the handling of result sets and query string retrieval, so two methods--one for the query, one for the results.
You'd pass an implementation to an instance of mostly what you have now, but it takes the interface instead of a query string. The rest of the code is essentially identical, but it gets the query string from the interface impl, and calls the interface impl's result handling method, saving the result until the cleanup.
It's essentially the same as you have now, but IMO cleaner since any class could implement the interface, including anonymous classes, or other classes in your domain.
You may be interested in using Apache Commons DbUtils which is aimed exactly at such purposes.
It has some drawbacks when trying to use more sophisticated JDBC but for regular usage it should be more than enough.
Besides that, your code contains too much try/catch blocks and can be simplified to something like the following:
public interface ResultSetHandler<ResultType> {
ResultType handleResultSet(ResultSet rs);
}
public <ResultType> ResultType getTransformedResults(String query, ResultSetHandler<ResultType> rsh) throws SQLException {
Connection connection = null;
Statement stmt = null;
try {
connection = dataSource.getConnection();
stmt = connection.createStatement();
ResultSet rs = stmtm.executeQuery(query);
return rsh.handleResultSet(rs);
} catch (SQLException sqle) {
// cleanup
throw sqle;
} finally {
if(stmt != null) {
statement.close(); // closes also resultSet
connection.close();
}
}
}
Though Apache Commons DbUtils library does exactly the same under the hood.
org.springframework.jdbc.core.JdbcTemplate - "...simplifies the use of JDBC and helps to avoid common errors."
Connection c = null;
Statement s = null;
ResultSet r = null;
try {
c = datasource.getConnection();
s = c.createStatement();
r = s.executeQuery(sql);
rsh.handleResultSet(r);
}
finally {
DbUtils.closeQuietly(r);
DbUtils.closeQuietly(s);
DbUtils.closeQuietly(c);
}
Note that DbUtils is apaache commons-dbutils, and the closeQuietly is equivalent to:
try {
c.close();
}
catch (SQLException e) {
}
This all being said, i'd recommend using spring's jdbc features:
JdbcTemplate template = new JdbcTemplate(dataSource);
List data = template.query(sql, new RowMapper() { ... });
The RowMapper is an interface whose implementation has the job of converting the current position in the resultset to an object. So by simply giving it the logic of what to do with one row, you automatically collect the list of the objects for all rows in these two lines of code plus whatever it takes to map the row. There's other methods which let you work with the ResultSet in different ways, but this is a pretty standard way in which people use it.
All the connection and statement management is done for you, and you don't have to worry about resource management at all.
I am (successfully) connecting to a database using the following:
java.sql.Connection connect = DriverManager.getConnection(
"jdbc:mysql://localhost/some_database?user=some_user&password=some_password");
What should I be checking to see if the connection is still open and up after some time?
I was hoping for something like connect.isConnected(); available for me to use.
Your best chance is to just perform a simple query against one table, e.g.:
select 1 from SOME_TABLE;
Oh, I just saw there is a new method available since 1.6:
java.sql.Connection.isValid(int timeoutSeconds):
Returns true if the connection has not been closed and is still valid.
The driver shall submit a query on the connection or use some other
mechanism that positively verifies the connection is still valid when
this method is called. The query submitted by the driver to validate
the connection shall be executed in the context of the current
transaction.
Nothing. Just execute your query. If the connection has died, either your JDBC driver will reconnect (if it supports it, and you enabled it in your connection string--most don't support it) or else you'll get an exception.
If you check the connection is up, it might fall over before you actually execute your query, so you gain absolutely nothing by checking.
That said, a lot of connection pools validate a connection by doing something like SELECT 1 before handing connections out. But this is nothing more than just executing a query, so you might just as well execute your business query.
Use Connection.isClosed() function.
The JavaDoc states:
Retrieves whether this Connection object has been closed. A
connection is closed if the method close has been called on it or if
certain fatal errors have occurred. This method is guaranteed to
return true only when it is called after the method Connection.close
has been called.
You also can use
public boolean isDbConnected(Connection con) {
try {
return con != null && !con.isClosed();
} catch (SQLException ignored) {}
return false;
}
If you are using MySQL
public static boolean isDbConnected() {
final String CHECK_SQL_QUERY = "SELECT 1";
boolean isConnected = false;
try {
final PreparedStatement statement = db.prepareStatement(CHECK_SQL_QUERY);
isConnected = true;
} catch (SQLException | NullPointerException e) {
// handle SQL error here!
}
return isConnected;
}
I have not tested with other databases. Hope this is helpful.
The low-cost method, regardless of the vendor implementation, would be to select something from the process memory or the server memory, like the DB version or the name of the current database. IsClosed is very poorly implemented.
Example:
java.sql.Connection conn = <connect procedure>;
conn.close();
try {
conn.getMetaData();
} catch (Exception e) {
System.out.println("Connection is closed");
}
Here is a simple solution if you are using JDBC to get the default connection
private Connection getDefaultConnection() throws SQLException, ApiException {
Connection connection = null;
try {
connection = dataSource.getConnection ();
}catch (SQLServerException sqlException) {
// DB_UNAVAILABLE EXCEPTION
}
return connection;
}