This code below is the “base” servlet we use for our project:
public class MyServlet extends Servlet {
private static final long serialVersionUID = 1L;
protected Connection conn;
/**
* @see HttpServlet#HttpServlet()
*/
public MyServlet() {
super();
}
protected void connectDB() throws NamingException, SQLException {
// get database settings
InitialContext cxt = new InitialContext();
DataSource ds =(DataSource)cxt.lookup( "java:/comp/env/jdbc/MyDB" );
conn = ds.getConnection();
}
protected void closeDB() throws SQLException {
try {
if (conn!=null) conn.close();
}
finally {
conn = null;
}
}
protected void addCacheControl(HttpServletResponse response) {
response.setHeader("Expires", "Thu, 01 Jan 1970 00:00:00 GMT");
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate, pre-check=0, post-check=0");
response.setHeader("Pragma", "no-cache");
}
}
For example SomeServlet extends MyServlet …
Now SomeServlet is access in the browser it do a forward() to a JSP page then it refresh for a certain period (say 10 sec.)
After a while that the page is open, this code throws NullPointerException:
stmt = conn.prepareCall("{call sp_someSP(?, ?, ?)}");
You cannot use instance fields of a Servlet like this, because it will be shared by multiple threads.
You need to explicitly pass the connection around as parameters and local variables through your program (so that they live on the stack, and each thread gets their own version), or maybe use a ThreadLocal if you want a more “global” approach. A ThreadLocal Connection can also be reliably closed by a ServletFilter when your request is done.