Here is my doPost method of my servlet that in theory add data in db
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
Date d=(Date) request.getAttribute("data");
DatiAnagrificiImpl dai=new DatiAnagrificiImpl();
dai.addDatiAnagrafici(new DatiAnagraficiBean(request.getParameter("username"),request.getParameter("cap"),request.getParameter("nome")
,request.getParameter("cognome"),request.getParameter("telefono"),d));
}
And here the method that will insert data in db
enter public void addDatiAnagrafici(DatiAnagraficiBean dab) {
// TODO Auto-generated method stub
try {
Statement s=c.createStatement();
s.executeUpdate("insert into Dati_anagrafici values('"+dab.getIdUtente()+"','"+dab.getIdCittà()+"',"
+ "'"+dab.getNome()+"','"+dab.getCognome()+"','"+dab.getTelefono()+"','"+dab.getDataNascita()+"')");
}catch(SQLException e) {
}finally {
al.add(dab);
}
}
But when I try to do that with a servlet I have this error
ERROR 1205 (HY000): Lock wait timeout exceeded;
Someone knows how to resolve? If I do the same thing with a normal java class is all fine.
It appears you have a transaction that's not completing. In MySQL, try running these to get a view into what's going on:
SHOW ENGINE INNODB STATUS;
SHOW FULL PROCESSLIST;
One or both should provide some clues.
A few issues stand out in your code. The first thing I would address is that the Statement is never closed (but should be). You can close the statement in a few places, but as the simplest example, you could close it right after you call executeUpdate(), like this:
Statement s = c.createStatement();
s.executeUpdate("...");
s.close();
Another easy change: when catching an exception, do something with it (instead of "swallowing" the exception silently). It's possible there's an exception being thrown, but the code above will hide that exception. For example, instead of this:
catch (SQLException e) {
}
try this:
catch (SQLException e) {
e.printStackTrace();
}
A final improvement would be to rework the code a bit to use "try-with-resources" - a nice convenience to automatically close a resource for you (in this case, your Statement). That could look like this:
Connection connection = getConnection();
try (Statement statement = connection.createStatement()) {
statement.executeUpdate("...");
} catch (SQLException e) {
e.printStackTrace();
}
EDIT: One more thing.. the connection can (and should) be committed by calling commit() (or rollback() if something went wrong). Here's a final edit to try which shows commit() in the main try block, and a rollback() in the catch block to undo the transaction if an exception is thrown:
Connection connection = getConnection();
try (Statement statement = connection.createStatement()) {
statement.executeUpdate("...");
connection.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
Related
Is it fine to have a nested try block without a catch or finally block and let the outer catch block handle the exception if any from the nested try block?
Something like:
try (Connection con = ds.getConnection();
PreparedStatement ps = con.prepareStatement(sql);) {
//nested try block without a catch or finally block
try (ResultSet rs = ps.executeQuery();) {
while (rs.next()) {
list.add(rs.getInt("id"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
If you remove the 'try' the result set will not close automatically.
The try-with-resources statement sort of executes rs.close in a hidden finally.
It is good practice to close the resultset, open resultset can lead to problems : java.sql.SQLException: - ORA-01000: maximum open cursors exceeded
Problem with exception catching in this example is how do you differentiate between datasource exceptions, query creation exceptions or query execution SQLExceptions? I would probably throw a specific RuntimeException when my datasource can not deliver an connection.
No. Your code won't compile.
Every try block (even nested) must be followed with catch(..) and/or finally.
In your case add a second catch block if you want to handle any other additional exceptions.
Sample code:
try {
// code which may throw exceptions
} catch(Exception e1) {
// e1 specific code
} catch (Exception e2) {
// e2 specific code
} finally {
// Optional. Executes whether exception thrown or not!
}
I have connection provider class as bleow to return connection.
public class ConnectionProvider {
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection ConnectDB() throws ClassNotFoundException, SQLException {
try (Connection connection = DriverManager
.getConnection("jdbc:mysql://localhost:3306/jspservlet_test","root", "root");
) {
return connection;
}
}
}
Here is main method to call connection provider.
public void Test() {
try {
Connection con = ConnectionProvider.ConnectDB();
PreparedStatement ps = con.prepareStatement("");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
But "com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed." error are always show at below line of code.
PreparedStatement ps = con.prepareStatement("");
Because, according to Oracle documentation, If use try with resources java 7 features, resources are auto close after try block even it's errors occurred or not. So even I returned the connection it's already closed.
Let me know, my usage logic is wrong?
How can I return this connection inside try with resource?
I tried many time googling for solution but does not get convenience answers for me.
Let me know your suggestion and feedback please.
What you can't do...
With a try-with-resources as you have it after you return the connection you return(d) is close(d). You can't return the connection from inside the try with resources.
What you can do...
Pass the connection (inside your try-with-resources) to a method that takes a connection. You can also use a ConnectionPool, and get the Connection when you need it (to create and execute a query).
Let me know, my usage logic is wrong?
The usage of 'try-with-resources' logic is wrong in this context, because the intention of ConnectDB() is to return a connection instance which could be actually used by the caller to send a SQL statement, but instead, the connection instance is getting auto-closed, before it could be used by the caller, because of using 'try-with-resources' construct of Java.
Quick how-to on try-with-resource and JDBC
Your ConnectionProvider's ConnectDB already declares it is throwing SQLException - so no need to catch it in here: (You should consider replacing this code with connection pool maybe)
public class ConnectionProvider {
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection ConnectDB() throws SQLException {
return DriverManager.getConnection("jdbc:mysql://localhost:3306/jspservlet_test","root", "root");
}
}
Instead use try-with-resource in your test-class to clean up your code and focus on errors your SQL code
might have:
public void Test() {
try (Connection con = ConnectionProvider.ConnectDB();
PreparedStatement ps = con.prepareStatement("SELECT 1")) {
//Prepare your Statement
ps.setInt(1, 1);
//And another try-with-resource for the result - note the closing brace
try(ResultSet rs = ps.executeQuery()) {
while(rs.next()) {
//Handle your Result
System.out.println(rs.getString(1));
}
} // This closes try-with-resource. Exception will be rethron to be caught in outer catch!
} catch (SQLException e) {
//SQL is Broken - but only ONE catch to catch them all
e.printStackTrace();
}
}
That way you gain
Better readability for your code (no calls to close surrounded by finally and if != null)
Centralized error handling if anything in your SQL code breaks (so you can focus on functional error of "statement didn't run")
Better code quality: No need to worry about Cursors, Statements, Connections not being propery closed.
A sever issue I am facing after deployment on Glassfish4 and Ubuntu 14.04 . In java, I am not using hibernate due to some reasons. I am manually getting the resultset as a result of query, sending the result set to JSP page and iterating over it.
Problem is, I have set the finally block as below:
finally {
try {
if (conn != null) {
conn.close();
}
if (ctx != null) {
ctx.close();
}
if (cstatement != null) {
cstatement.closeOnCompletion();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And because I am sending the Resultset to JSP page through session, I am closing the result on JSP page as follows:
if(resultset!=null) resultset.close();
Now, problem is, after few minutes my application starts giving exception that max of the connection pools has been used.
What should I do to avoid exception?
The problem with your current finally block is:
If any exception is thrown from one of the close command, the following command will not be run. Since the issue seems to be resource leak so that might be the cause.
If you are running under JDK7+ and the resource is auto-closable, try to use
try(Connection conn=DriverManager.getConnection();
Statement stat=conn.createStatement){
}
Then the resources will be closed safely exiting try block.
And if you need to close resource from finally block, try to wrap a try catch for each close statement.
For ordering of closing resource, always close the resource you created later first.
I have a stateless session bean a method of which is used repetitively for running an SQL query within a plain JDBC connection. To avoid having to open and close connections too frequently, I came up with the following approach and wondering if it is a good practice:
I open the connection once in a method annotated #PostConstruct and close the connection in another method annotated #PreDestroy
The code works fine with no apparent memory leaks or any issues that I know of - just wondering if more experienced developers would agree if it is a good practice.
#PostConstruct
public void initBean() {
try {
conn = Connector.getConnection();
} catch (Exception e) {
// Handle errors for Class.forName
e.printStackTrace();
}
}
public String runTheQuery(String sql) {
String result ="";
try {
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
result = rs.getString(1);
rs.close();
pstmt.close();
} catch (SQLException se) {
// Handle errors for JDBC
}
return result;
}
#PreDestroy
public void endingTitles() {
System.out.println("Closing the JDBC connection...");
try {
rs.close();
conn.close();
pstmt.close();
} catch (SQLException se) {
// Handle errors for JDBC
se.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
// finally block used to close resources
try {
if (pstmt != null)
pstmt.close();
} catch (SQLException se2) {
}// nothing we can do
try {
if (conn != null)
conn.close();
} catch (SQLException se) {
se.printStackTrace();
}// end finally try
}// end try
}
The best solution is to use DataSource
#Resource(mappedName="java:/DefaultDS")
DataSource dataSource;
public String runTheQuery(String sql) throws SQLException
Connection con = dataSource.getConnection();
try {
...
} finally {
con.close();
}
}
Data sources normally always have a minimum number of open connections, so in most cases there will be no real overhead getting a connection from a data source.
So it's only a valid practice, if you have measured before, and it it really solves an existing performance problem.
Otherwise it's not common, and therefore it's something like premature performance optimization.
Data sources offer additonal functionality: For example to check a connection, if it's still valid, before it gets injected. If you did it yourself, you would have to reimplement it. And there are possibly errors in that code.
Is there anything wrong with using a parent function to handle all the messy catch/finally stuff in a connection pool?
public Connection getConnection() {
try {
return this.dataSource.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public ResultSet executeQuery(Connection connection, PreparedStatement stmt) {
try {
return stmt.executeQuery();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
No problem except the fact that you are eating the exceptions and not throwing them.Throwing an exception is a better idea to allow the calling methods to take appropriate actions.
Note: if you can move to Java 7 and use try with resource then you will save a lot of such mess. Learn more about it here: http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
This is an example of the Facade Pattern.
There's nothing wrong with it, except your should make those methods static, so they are (stateless) utility methods.
You'll have much cleaner code if you use the try-with-resources pattern and focus on minimizing the scope of your resources. In particular, you problematically open resources (the connection and the statement) separately from the close behavior. By splitting it up, you make it easy to make mistakes, or create inefficient code. For example, perhaps you should not close the connection after executing the query.
Instead, you should generally open and close resources in the same place, and anywhere you pass around these resources you trust (create an invariant) that they are and will remain open. This cleanly compartmentalizes the obtaining-resources behavior from the using-resources behavior, and lets you clearly limit the scope these resources are open for.
Compare your code:
Connection conn = getConnection();
PreparedStatement ps = ...; // construct PreparedStatement
ResultSet rs = executeQuery(conn, ps);
// use ResultSet
/* now secretly your Connection and PreparedStatement are closed (even if you wanted
to use them again) though your result set is still open and needs to be closed.
Admittedly it's concise, but what's actually going on is very unclear. */
To my code:
public static void main(String[] args) {
try(Connection conn = this.dataSource.getConnection()) {
// All calls in this block, and only calls in this block, can use the connection
buildObjectWithDBData(conn); // method does exactly what the name implies
// do more calls against our connection as needed
}
}
public static void buildObjectWithDBData(Connection conn) {
try(PreparedStatement ps = /* generate prepared statement */;
ResultSet rs = ps.executeQuery()) {
// do work with result set, populate the data we need
}
// at this point we know the connection is alive in a clean, stable state,
// the resources opened here are closed, and we've done the work we need
}
I'll grant, mine is a little more verbose. But it's much more clear what it's doing, and at every step in the process we explicitly limit the scope of our objects and resources to as little as possible, rather than relying on side-effects of arbitrary method calls to secretly close objects and leave them still in scope, but unusable.