SQLException Operation not allowed after ResultSet closed - java

I am attempting to write a JUnit test for a query which is retrieved via a textbox in an html form. The text retrieval has been tested and works but my unit test is failing. I am using 2 relevant classes: QueryController and QueryControllerTest. I have been playing around with when and what I am closing in these two classes and keep getting the error: Operation not allowed after ResultSet closed.
QueryControllerTest.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
import static org.junit.Assert.*;
public class QueryControllerTest {
#Test
public void testQuery() {
ResultSet testRs = null;
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String connectionUrl = "jdbc:mysql://localhost:3306/test";
String connectionUser = "root";
String connectionPassword = "GCImage";
conn = DriverManager.getConnection(connectionUrl,
connectionUser, connectionPassword);
Query testQuery = new Query();
testQuery
.setQuery("select * from service_request where FN_contact = 'Greg'");
testRs = QueryController.executeSelect(conn, testQuery);
assertEquals("Laughlin", testRs.getString("LN_contact"));
assertEquals("Hello World", testRs.getString("Notes"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
testRs.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
QueryController.java
import java.util.Map;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class QueryController {
#RequestMapping(value = "/query")
public String processRegistration(#ModelAttribute("query") Query query,
Map<String, Object> model) {
String queryString = query.getQuery();
if (queryString != null && !queryString.isEmpty()) {
System.out.println("query (from controller): " + queryString);
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String connectionUrl = "jdbc:mysql://localhost:3306/test";
String connectionUser = "root";
String connectionPassword = "GCImage";
conn = DriverManager.getConnection(connectionUrl,
connectionUser, connectionPassword);
if (queryString.toLowerCase().startsWith("select")) {
ResultSet rs = executeSelect(conn, query);
} else {
int rowsUpdated = executeUpdate(conn, query);
System.out.println(rowsUpdated + " rows updated");
}
} catch (Exception e) {
e.printStackTrace();
}
}
return "query";
}
public static ResultSet executeSelect(Connection conn, Query query) {
ResultSet rs = null;
Statement stmt = null;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(query.getQuery());
while (rs.next()) {
String id = rs.getString("ID");
String firstName = rs.getString("FN_Contact");
String lastName = rs.getString("LN_Contact");
String notes = rs.getString("Notes");
System.out.println("ID: " + id + ", First Name: " + firstName
+ ", Last Name: " + lastName + ", Notes: " + notes);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(rs!=null){
rs.close();
}
if(stmt != null){
stmt.close();
}
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return rs;
}
}

QueryController.executeSelect is calling rs.close(), but then your assertEquals in QueryControllerTest.testQuery are calling methods on testRS. As executeSelect is returning the resultset, closing it first doesn't make sense. Further, executeSelect is being passed the connection, so it shouldn't be closing that either (what happens if the caller wants to do two different selects on the same connection?).

I think the problem is because you are creating two connections. Try to only instantiate the connection of QueryController class for your test. You will need to provide the connection. After you store it in a variable to run the query.
Connection con = QueryController.getConnection ();

Related

Creating database and tables directly from Java

I'm trying to create the tables directly form Java instead of creating them using phpMyAdmin. The code looks like that runs smooth, but when the queries arrive, it gives some kind of error that I'm trying to identify and I'm not capable. Here's the code I've been trying:
package filmoteca;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class GestionBDD {
private static String datosConexion = "jdbc:mysql://127.0.0.1:3306/";
private static String baseDatos = "cine";
private static String usuario = "root";
private static String pass = "";
private static String tabla = "pelicula";
private Connection con;
public GestionBDD() {
try {
con = DriverManager.getConnection(datosConexion, usuario, pass);
try{
crearBDD();
crearTablas();
}catch(Exception e){
e.printStackTrace();
}
}catch(SQLException e) {
e.printStackTrace();
}
}
public void crearBDD() throws Exception{
String query = "CREATE DATABASE IF NOT EXISTS"+ baseDatos +";";
Statement stat = null;
try{
stat = con.createStatement();
stat.executeUpdate(query);
con = DriverManager.getConnection(datosConexion+baseDatos, usuario, pass);
}catch(SQLException e){
e.printStackTrace();
}finally{
stat.close();
}
}
public void crearTablas() throws Exception{
String query = "USE DATABASE "+baseDatos+";"+
"CREATE TABLE IF NOT EXISTS"+" "+tabla+"("
+ "titulo VARCHAR(30), "
+ "director VARCHAR(30), "
+ "pais VARCHAR(30), "
+ "duracion FLOAT, "
+ "genero VARCHAR(30));";
Statement stat = null;
try{
stat = con.createStatement();
stat.executeUpdate(query);
con = DriverManager.getConnection(datosConexion+baseDatos, usuario, pass);
}catch(SQLException e){
e.printStackTrace();
}finally{
stat.close();
}
}
}

Data Access object method not working

I am a student learning JSP, and I seem to have this issue in executing a method via an object of a DAO class. When the database connectivity and SQL query is given on the servlet itself it, it will work. But when given in the DAO class and a object is used, it doesn't work. Please help.
import dataaccessobjects.cartDAO1;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class addtoCartServ extends HttpServlet {
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
cartDAO1 newcart = new cartDAO1();
PrintWriter out = response.getWriter();
if (request.getParameter("submit") != null){
//out.println("added to cart");
try {
//out.println("submit not null");
String Uname = (String) request.getSession().getAttribute("Welcome");
String ino = request.getParameter("ino");
String iqnty = request.getParameter("quantity");
String iname = request.getParameter("iname");
if(newcart.addToCart(iname,Uname,ino,iqnty)){
out.println("added to cart");
}
} catch (SQLException ex) {
Logger.getLogger(addtoCartServ.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(addtoCartServ.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
The DAO class
public cartDAO1(){
}
public boolean addToCart(String iname,String username, String ino,String iqnty) throws SQLException, ClassNotFoundException{
boolean flag = false;
Class.forName("org.apache.derby.jdbc.ClientDriver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/styleomega","root","");
PreparedStatement ps = conn.prepareStatement("INSERT INTO cart(iname,uname,ino,iqnty) VALUES (?,?,?,?)");
// set the values for parameters
ps.setString(1,iname);
ps.setString(2,username);
ps.setString(3,ino);
ps.setString(4,iqnty);
int rs = ps.executeUpdate();
if (rs==1){
flag = true;
}
return flag;
}
}
You should be import the DAO class package in servlet then access it it will work like
import DAO.cartDao;
If you will not import then how to acces it
I don't understand exactly what is not working? But I have noticed, you're not closing statement and the database connection in your DAO class.
FYI: An example
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = // Retrieve connection
stmt = conn.prepareStatement(// Some SQL);
rs = stmt.executeQuery();
} catch(Exception e) {
// Error Handling
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) {};
try { if (stmt != null) stmt.close(); } catch (Exception e) {};
try { if (conn != null) conn.close(); } catch (Exception e) {};
}

JDBC programming

I am working in command prompt this is my code
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBC {
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException cnf) {
System.out.println("Driver could not be loaded: " + cnf);
}
}
public static void main(String[] args)
{
String connectionUrl = "jdbc:mysql://localhost:3306/mysql";
String dbUser = "root";
String dbPwd = "admin";
Connection conn;
ResultSet rs;
String queryString = "SELECT ID, NAME FROM exptable";
try {
conn = DriverManager.getConnection(connectionUrl, dbUser, dbPwd);
Statement stmt = conn.createStatement();
// INSERT A RECORD
stmt.executeUpdate("INSERT INTO exptable (name) VALUES (\"TINU K\")");
// SELECT ALL RECORDS FROM EXPTABLE
rs = stmt.executeQuery(queryString);
System.out.println("ID \tNAME");
System.out.println("============");
while (rs.next()) {
System.out.print(rs.getInt("id") + ".\t" + rs.getString("name"));
System.out.println();
}
if (conn != null) {
conn.close();
conn = null;
}
} catch (SQLException sqle) {
System.out.println("SQL Exception thrown: " + sqle);
}
}
}
i am getting error like
java.lang.ClassNotFoundException and java.sql.SQLException
so may i know what mistake have i made
You might have missed the classpath in your java command. While executing from command prompt you must mention the class path along with your command.
java -cp
ex:
java -cp /home/test/jars:/home/test/src com.test.Lab

MySQLConnection - Error on authenticateUser of "Multiple markers at this line"

I am trying to create my first MySQLConnection in Eclipse and am getting an error on authenticateUser of "Multiple markers at this line
- The return type is incompatible with
DBConnection.authenticateUser(String, String)"
I understand this means "that there is more than one error ... but I can't solve the issue...".
I am using http://altair.cs.oswego.edu/~tenberge/tenbergen.org/misc/DB-Access-in-GWT-The-Missing-Tutorial.pdf as my guide.
This is my code:
AwardTracker.gwt.xml
<module>
<inherits name="com.google.gwt.user.User"/>
<inherits name="com.google.gwt.user.theme.standard.Standard"/>
<entry-point class="org.AwardTracker.client.AwardTracker"/>
<!-- servelet context - path is arbitrary, but must match up with the rpc init inside java class -->
<!-- Tomcat will listen for this from the server and waits for rpc request in this context -->
<servelet class="org.AwardTracker.server.MySQLConnection"
path="/MySQLConnection" />
<inherits name="com.google.gwt.user.theme.standard.Standard"/>
<inherits name="com.google.gwt.user.theme.chrome.Chrome"/>
<inherits name="com.google.gwt.user.theme.dark.Dark"/>
User.java
package org.AwardTracker.client;
import com.google.gwt.user.client.rpc.IsSerializable;
public class User implements IsSerializable {
#SuppressWarnings("unused")
private String username;
#SuppressWarnings("unused")
private String password;
#SuppressWarnings("unused")
private User() {
//just here because GWT wants it.
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
}
MySQLConnection.java
package org.AwardTracker.server;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.AwardTracker.client.DBConnection;
import org.AwardTracker.client.User;
public class MySQLConnection extends RemoteServiceServlet implements DBConnection {
private Connection conn = null;
private String status;
private String url = "jbdc:mysql://localhost/awardtracker";
private String user = "DBuser";
private String pass = "DBpass";
public MySQLConnection() {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(url, user, pass);
} catch (Exception e) {
//NEVER catch exceptions like this
}
}
public int authenticateUser(String user, String pass) {
User user;
try {
PreparedStatement ps = conn.prepareStatement(
"select readonly * from users where username = \"" + user + "\" AND " + "password = \"" + pass + "\"");
ResultSet result = ps.executeQuery();
while (result.next()) {
user = new User(result.getString(1), result.getString(2));
}
result.close();
ps.close();
} catch (SQLException sqle) {
//do stuff on fail
}
return user;
}
}
Any help would be greatly appreciated.
Regards,
Glyn
Hi BenvynQ,
Thanks for your help. Just goes to show that these tutorials are not perfect. I made this change and now I get an error within authenticateUser:
while (result.next()) {
user = new User(result.getString(1), result.getString(2));
}
Of "The constructor User(String, String) is undefined".
Thanks,
Glyn
Hi Bevnq,
Thanks awfully for your help. I think there were a few "}" missing so I have modified as following.
Also, you say "User user = null; // necessary unless you do something in the exception handler
". My impression of this is that we are trying to find out if the user is in the table and return an exception if they are not (i.e., verify the username and password). Therefore, the return needs to be a confirmation and therefore we are doing something with the exveption handler. I am obviously missing something; so how do we know the user has logged in successfully?
Also, Eclipse does not seem to have an issue with mixed case for the package as I am doing this in stages and all has worked up to adding this.
Regards,
Glyn
package org.AwardTracker.server;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.AwardTracker.client.DBConnection;
import org.AwardTracker.client.User;
public class MySQLConnection extends RemoteServiceServlet implements DBConnection {
private Connection conn = null;
private String status;
private String url = "jbdc:mysql://localhost/awardtracker";
private String user = "DBuser";
private String pass = "DBpass";
public MySQLConnection() {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(url, user, pass);
} catch (Exception e) {
//NEVER catch exceptions like this
}
}
public User authenticateUser(String userName, String pass) {
User user = null; // necessary unless you do something in the exception handler
ResultSet result = null;
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(
"select readonly * from users where username = \"" + userName + "\" AND " + "password = \"" + pass + "\"");
result = ps.executeQuery();
while (result.next()) {
user = new User(result.getString(1), result.getString(2));
}
}
catch (SQLException sqle) {
//do stuff on fail
}
finally {
if (result != null) {
try {
result.close();
}
catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
return user;
}
}
You have defined the method
public int authenticateUser(String user, String pass) {
yet the object you are returning is
User user;
reading the tutorial looks like you should have declared the method
public User authenticateUser(String userName, String pass) {
User user = null; // necessary unless you do something in the exception handler
ResultSet result = null;
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(
"select readonly * from users where username = \"" + userName + "\" AND " + "password = \"" + pass + "\"");
result = ps.executeQuery();
while (result.next()) {
user = new User(result.getString(1), result.getString(2));
}
} catch (SQLException sqle) {
//do stuff on fail
}finally{
if (result != null) {
try {
result.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return user;

NPE - java.lang.reflect.UndeclaredThrowableException

I'm working on web java application with OSGI. I get this error when I try to open JSF page: java.lang.reflect.UndeclaredThrowableException
This is the source code that I'm working on:
package org.DX_57.osgi.SH_27.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.DX_57.osgi.SH_27.api.SessionHandle;
public class SessionHandleImpl implements SessionHandle {
#Resource(name="jdbc/Oracle")
public DataSource ds;
public String sayHello(String name) {
return "Howdy " + name;
}
public String CheckUserDB(String userToCheck){
String storedPassword = null;
String error_Message = null;
String SQL_Statement = null;
String error_Database;
Connection conn;
try {
conn = ds.getConnection();
try {
conn.setAutoCommit(false);
boolean committed = false;
try {
SQL_Statement = "SELECT Passwd from USERS WHERE Username = ?";
PreparedStatement passwordQuery = conn.prepareStatement(SQL_Statement);
passwordQuery.setString(1, userToCheck);
ResultSet result = passwordQuery.executeQuery();
if(result.next()){
storedPassword = result.getString("Passwd");
}
conn.commit();
committed = true;
} finally {
if (!committed) conn.rollback();
}
}
finally {
conn.close();
}
} catch (SQLException ex) {
ex.printStackTrace();
}
return storedPassword;
}
}
This is the error stack of the Glassfish server: http://pastebin.com/tvHmspjh
I can successfully compile the code but when I try to open JSF page I get error. Maybe I have mistaken the try-catch statements.
Best wishes

Categories