"Operation not allowed after ResultSet closed" with Datasource and crawler4j - java

After reading through a lot of similar questions I have not been able to get a solution that works for me.
I have this methods:
In a crawler4j Controller I do this:
ArrayList<String> urls = Urls.getURLs(100);
for (String s : urls) {
System.out.println("Adding URL: " + s);
controller.addSeed(s);
}
this is getURLs():
public static ArrayList<String> getURLs(int number) {
ArrayList<String> list = new ArrayList<String>();
String getStatement = "select * from " + Configurations.getStringProperty("mysql.urls.db_name", "urls") + " where retrieved=0 limit "
+ Configurations.getStringProperty("mysql.urls.limit", "100") + ";";
ResultSet rs;
rs = Databaseclient.executeStatement(getStatement);
try {
while (rs.next()) {
list.add(rs.getString("url"));
// Databaseclient.executeStatement("update urls set retrieved = true where id = "
// + rs.getInt("id") + ";");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return list;
}
This is my executeStatement():
public static ResultSet executeStatement(String s) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// fetch a connection
connection = DataSource.getInstance().getConnection();
if (connection != null) {
statement = connection.createStatement();
resultSet = statement.executeQuery(s);
}
} catch (SQLException e) {
System.out.println("A SQLException occured executing the Statement");
e.printStackTrace();
} catch (IOException e) {
System.out.println("A IOException occured executing the Statement");
e.printStackTrace();
} catch (PropertyVetoException e) {
System.out.println("A PropertyVetoException occured executing the Statement");
e.printStackTrace();
} finally {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
System.out.println("A SQLException occured executing the Statement");
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
System.out.println("A SQLException occured executing the Statement");
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
System.out.println("A SQLException occured executing the Statement");
e.printStackTrace();
}
}
}
return resultSet;
}
I get the error
java.sql.SQLException: Operation not allowed after ResultSet closed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1094)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:997)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:983)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:928)
at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:799)
at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:6982)
at database.Urls.getURLs(Urls.java:27)
at crawler.Controller.main(Controller.java:53)
Which is the line
while (rs.next()) {
in my getURLs() method.
What am I doing wrong? There is no code between getting the statement and the while loop that could close the statement.

Your code is a bit off, but if I understand you then don't close your ResultSet in the finally block of your executeStatement method.
public static ResultSet executeStatement(Connection connection,
Statement statement, String s) {
ResultSet resultSet = null;
try {
if (statement != null) {
resultSet = statement.executeQuery(s);
}
} catch (SQLException e) {
System.out.println("A SQLException occured executing the Statement");
e.printStackTrace();
} catch (IOException e) {
System.out.println("A IOException occured executing the Statement");
e.printStackTrace();
} catch (PropertyVetoException e) {
System.out.println("A PropertyVetoException occured executing the Statement");
e.printStackTrace();
}
return resultSet;
}
Then you need to pass in a Connection and Statement, and you'll get a ResultSet back. Also, the caller should then close all three when it's done with the ResultSet.

Related

Why is there an Operation not allowed after ResultSet closed in my code?

I am getting an "Operation not allowed after ResultSet closed error" for the below code block. I am creating a new instance of connection for each request and closing them off in the finally block.
public int getUserIdBasedOnAlias(String alias){
int i=0;
ResultSet rs=null;
java.sql.CallableStatement cstmt=null;
DBHelper dbh=new DBHelper();
java.sql.Connection con=dbh.getConnection();
try{
cstmt=con.prepareCall("{call sp_GetUserIdBasedOnAlias(?)}");
cstmt.setString(1,alias);
rs=cstmt.executeQuery();
while(rs.next()){ // *** ERROR IS HERE ***
i=rs.getInt("UserId");
}
}
catch(SQLException e){
e.printStackTrace();
}
finally{
try {
dbh.close(rs, cstmt, con);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return i;
}
Below is the code in the DBHelper class
public Connection getConnection() {
//Loading JDBC Driver Class
try{
Class.forName("com.mysql.jdbc.Driver");
}
catch (ClassNotFoundException e){
e.printStackTrace();
}
try{
con=DriverManager.getConnection(conUrl,userName,pwd);
}
catch (SQLException e){
e.printStackTrace();
}
return con;
}
public void close(ResultSet rs, CallableStatement cstmt, Connection con) throws SQLException {
try {
try {
if (rs!=null) rs.close();
} finally {
if (cstmt!=null) cstmt.close();
}
} finally {
if (con!=null) con.close();
}
}
Stack trace:
java.sql.SQLException: Operation not allowed after ResultSet closed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910)
at com.mysql.jdbc.ResultSet.checkClosed(ResultSet.java:666)
at com.mysql.jdbc.ResultSet.next(ResultSet.java:7274)
at COM.FRMC.PKG.Employee.getUserIdBasedOnAlias(Employee.java:101)
Procedure Declaration:
Delimiter $$
Create Procedure sp_GetUserIdBasedOnAlias
(
in aliasname nvarchar(50)
)
Begin
Select 1 as UserId;
End$$
Delimiter ;
This is the working code:
public int getUserIdBasedOnAlias(String alias) throws SQLException{
int i=0;
DBHelper dbh=new DBHelper();
ResultSet rs=null;
CallableStatement cstmt=null;
java.sql.Connection con=dbh.getConnectionToFRMC_RiskAssessment();
try{
CallableStatement ct = con.prepareCall("{CALL sp_GetUserIdBasedOnAlias(?)}");
ct.setString(1,alias);
ct.execute();
ResultSet rs1=ct.getResultSet();
while(rs1.next()){
i=rs1.getInt(1);
}
}
catch(SQLException e){
e.printStackTrace();
}
finally{
try {
dbh.close(rs, cstmt, con);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return i;
}

Statement Leakage in JDBC

Statement Leakage in JDBC:
pstmt =
StatementLeakage : An open JDBC Statement is not closed on all paths. This can cause a transaction or Statement resources to remain active indefinitely, slowing or preventing access to the database by other requests.: for (object created at line = TunnelDBHandler:139, type = java.sql.PreparedStatement), object used at prepareStatement() # TunnelDBHandler:139
dbManager
.getConnection()
.prepareStatement(
"update TUNNEL_STORE set IS_TUNNEL_OPEN=? where TUNNEL_ID=?");
Add a finally block and call close() on all of your ResultSet(s), Statement(s) and Connection(s). As a very rough example,
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// ...
// get a statement for stmt
// get a resultset from the stmt
// ...
while (rs.next()) {
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
}
}
}

insert single data in data base but in data base duplicate row also added at time of insertion

I would like to insert single data in data base at a time but in data base duplicate row generate at a time.
-----------------------------
Output(in mysql table=privilege)
-----------------------------
id privilege
1 abc
2 abc
Here's how I insert the data:
public int addPrivilege(String privilege) {
PreparedStatement preparedStatement = null;
String sqlprivilege;
Connection dbConnection = null;
int pinsert = 0;
try {
sqlprivilege = "insert into privilege(privilege) values(?)";
dbConnection = ConnectionDao.getDBConnection();
preparedStatement = dbConnection.prepareStatement(sqlprivilege);
preparedStatement.setString(1, privilege);
pinsert = preparedStatement.executeUpdate();
if(preparedStatement.executeUpdate()==1)
pinsert=1;
else
pinsert=0;
System.out.println("privilege is add and name is:- " +privilege);
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dbConnection != null) {
try {
dbConnection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return pinsert;
}
You execute the sql twice in your code.
1) pinsert = preparedStatement.executeUpdate();
2) if(preparedStatement.executeUpdate()==1)
I'm not sure about the return values of the executeUpdate. But i think the first is enough, no need to check for the return values. If you need to then compare with pinsert instead of executeupdate (again).
if(pinsert == 1)
You are using two time executeUpdate(); delete execute which one is in if case
public int addPrivilege(String privilege) {
PreparedStatement preparedStatement = null;
String sqlprivilege;
Connection dbConnection = null;
int pinsert = 0;
try {
sqlprivilege = "insert into privilege(privilege) values(?)";
dbConnection = ConnectionDao.getDBConnection();
preparedStatement = dbConnection.prepareStatement(sqlprivilege);
preparedStatement.setString(1, privilege);
pinsert = preparedStatement.executeUpdate();
//try this
if(pinsert ==1)
pinsert=1;
else
pinsert=0;
System.out.println("privilege is add and name is:- " +privilege);
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dbConnection != null) {
try {
dbConnection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return pinsert;
}

Why i can't connect to mysql database in java?

I found this code in a tutorial but it isn't working when I debug it try the connection and then it isn't throw exception only go to the finally block without do any line of code under the DriverManager.getConnection().
Why? Anyone has an idea?
Connection con = null;
Statement st = null;
ResultSet rs = null;
String url = "jdbc:mysql://host/databasename";
String user = "user";
String password = "pass";
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
con = (Connection) DriverManager.getConnection(url, user, password);
st = (Statement) con.createStatement();
rs = st.executeQuery("SELECT * FROM Message");
if (rs.next()) {
System.out.println(rs.getString(1));
}
} catch (SQLException ex) {
Logger lgr = Logger.getLogger(Version.class.getName());
lgr.log(Level.SEVERE, ex.getMessage(), ex);
} catch (java.sql.SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
finally {
try {
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
if (con != null) {
con.close();
}
} catch (SQLException ex) {
Logger lgr = Logger.getLogger(Version.class.getName());
lgr.log(Level.WARNING, ex.getMessage(), ex);
} catch (java.sql.SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Logcat write this:
Logcat Message
1) DriverManager.getConnection() returns an object of type Connection, so there is no need to cast it. Same thing for st = (Statement) con.createStatement();
2) Unless you're running MySQL on a remote machine, you need to make sure you have MySQL installed on your local machine. If you decide to run MySQL on your local machine, you can connect to it with String url = "jdbc:mysql://localhost/{existing_db_name}"; given that everything else remains the same.
3) It seems like you're catching the same exception twice:
try{
con = (Connection) DriverManager.getConnection(url, user, password);
...
}catch (SQLException ex) {
Logger lgr = Logger.getLogger(Version.class.getName());
lgr.log(Level.SEVERE, ex.getMessage(), ex);
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
As a result, your second catch block, the one that prints the exception message to System.err, never runs. Instead, you print the exception message to a Logger. This might be why you think no exception is being thrown, when in reality, an exception is being thrown.
4) Make sure you download the JDBC driver for MySQL. Copy and paste it into the directory of your project.
I've deleted some catch block:
Connection con = null;
Statement st = null;
ResultSet rs = null;
String url = "jdbc:mysql://host:3306/databasename";
String user = "user";
String password = "pass";
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
con = (Connection) DriverManager.getConnection(url, user, password);
st = (Statement) con.createStatement();
rs = st.executeQuery("SELECT * FROM Message");
if (rs.next()) {
System.out.println(rs.getString(1));
}
} catch (SQLException ex) {
ex.printStackTrace();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
finally {
try {
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
if (con != null) {
con.close();
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
Can you please specify what String url are you using? At this point, with these modifications I obviously get a SQLException with No suitable driver found for jdbc:mysql://host/databasename

org.apache.commons.dbcp.DelegatingPreparedStatement is closed

org.apache.commons.dbcp.DelegatingPreparedStatement
is closed
Could i know in which situations this exception will come.
I closed all result sets and prepared statements.
How can i solve this problem.
Code :
public int UpdateMovementLines(List<MaterialRequestIssuanceVO> mlinelist,String projId,String documentno,String user){
int count = 1;
int line = 0;
String uom = null;
String projLocatorId = null;
String projWarehouseId = null;
String warehouseLocatorId = null;
String issuanceId = null;
String movementLineId =null;
String pinstanceId = null;
String sqlQry = null;
String whLocatorId = null;
PreparedStatement ps = null;
PreparedStatement ps1 = null;
PreparedStatement ps2 = null;
PreparedStatement ps3 = null;
PreparedStatement ps4 = null;
PreparedStatement ps5 = null;
ResultSet rs = null;
ResultSet rs1 = null;
ResultSet rs2 = null;
ResultSet rs3 = null;
try{
conn.setAutoCommit(false);
try{
sqlQry="INSERT INTO m_movement (m_movement_id, AD_CLIENT_ID, AD_ORG_ID, CREATED, CREATEDBY, UPDATED, UPDATEDBY," +
"name, movementdate, posted, processing, move_fromto_locator,documentno) VALUES " +
"(?,?,?,NOW(),?,NOW(),?,to_char(now(),'DD-MM-YYYY'),now(),?,?,?,?)";
ps = conn.prepareStatement(sqlQry);
for(MaterialRequestIssuanceVO movementvo:mlinelist){
issuanceId = movementvo.getIssuanceid();
ps.setString(1, issuanceId);
ps.setString(2,movementvo.getClientid());
ps.setString(3,movementvo.getOrgid());
ps.setString(4, movementvo.getCreatedby());
ps.setString(5,movementvo.getUpdatedby());
ps.setString(6,"N");
ps.setString(7,"N");
ps.setString(8,"N");
ps.setString(9, documentno);
count=ps.executeUpdate();
}
}
catch (SQLException e) {
// TODO Auto-generated catch block
log4j.info("Inside DB Line saveMRIssuanceMovementData Exception"+e);
}
finally
{
try
{
ps.close();
log4j.info("Inside Line Finally");
} catch (SQLException e) {
e.printStackTrace();
}
}
ps=conn.prepareStatement("select c_uom_id as uom from m_product where m_product_id = ?");
for(MaterialRequestIssuanceVO movementvo:mlinelist){
line = line +10;
ps.setString(1, movementvo.getMaterialid());
rs = ps.executeQuery();
while(rs.next())
{
uom = rs.getString("uom");
log4j.info("Uom: "+uom);
}
try{
ps2=conn.prepareStatement("select m_locator_id as locatorid from m_locator where m_warehouse_id = ?");
ps2.setString(1, movementvo.getWarehouseId());
rs2 = ps2.executeQuery();
while(rs2.next())
{
warehouseLocatorId = rs2.getString("locatorid");
log4j.info("warehouseLocatorId: "+warehouseLocatorId);
}
}catch(SQLException e){
log4j.info("Warehouse Locator Exception: "+e);
}
finally{
rs2.close();
ps2.close();
}
try{
ps3=conn.prepareStatement("select m_locator_id as locatorid from m_locator where m_warehouse_id=? and value like ?");
ps3.setString(1, movementvo.getWarehouseId());
ps3.setString(2, projId);
rs3 = ps3.executeQuery();
if(rs3.next())
{
projLocatorId = rs3.getString("locatorid");
log4j.info("projLocatorId: "+projLocatorId);
}
else
{
sqlQry="INSERT INTO m_locator (m_locator_id, AD_CLIENT_ID, AD_ORG_ID, CREATED, CREATEDBY, UPDATED, UPDATEDBY," +
"value, m_warehouse_id, priorityno, x,y, z) VALUES " +
"(?,?,?,NOW(),?,NOW(),?,?,?,?,?,?,?)";
ps4 = conn.prepareStatement(sqlQry);
try
{
whLocatorId = SequenceIdData.getUUID();
log4j.info("issueid: "+whLocatorId);
ps4.setString(1, whLocatorId);
log4j.info("Client Id: "+movementvo.getClientid());
ps4.setString(2,movementvo.getClientid());
log4j.info("Orgid: "+movementvo.getOrgid());
ps4.setString(3,movementvo.getOrgid());
ps4.setString(4, movementvo.getCreatedby());
ps4.setString(5,movementvo.getUpdatedby());
ps4.setString(6,projId);
ps4.setString(7,movementvo.getWarehouseId());
ps4.setInt(8,50);
ps4.setString(9,"x");
ps4.setString(10,"y");
ps4.setString(11,"z");
count=ps4.executeUpdate();
if(count == 1)
projLocatorId = whLocatorId;
}
catch(SQLException e)
{
log4j.info("M_Locator Exception: "+e);
}
finally
{
ps4.close();
}
log4j.info("whLocatorId projLocatorId: "+projLocatorId);
}
}catch(SQLException e){
log4j.info("Locator Exception: "+e);
}
finally{
rs3.close();
ps3.close();
}
try{
sqlQry="INSERT INTO m_movementline (m_movementline_id, AD_CLIENT_ID, AD_ORG_ID, CREATED, CREATEDBY, UPDATED, UPDATEDBY," +
"m_movement_id, m_locator_id, m_locatorto_id, m_product_id,line, movementqty,c_uom_id,m_attributesetinstance_id) VALUES " +
"(?,?,?,NOW(),?,NOW(),?,?,?,?,?,?,?,?,?)";
ps1 = conn.prepareStatement(sqlQry);
movementLineId = SequenceIdData.getUUID();
ps1.setString(1, movementLineId);
ps1.setString(2,movementvo.getClientid());
ps1.setString(3,movementvo.getOrgid());
ps1.setString(4, movementvo.getCreatedby());
ps1.setString(5,movementvo.getUpdatedby());
ps1.setString(6,issuanceId);
ps1.setString(7,warehouseLocatorId);
ps1.setString(8,projLocatorId);
ps1.setString(9,movementvo.getMaterialid());
ps1.setInt(10,line);
ps1.setInt(11,Integer.parseInt(movementvo.getIssuedqty()));
ps1.setString(12,uom);
ps1.setString(13,"0");
count=ps1.executeUpdate();
}
catch(SQLException e){
log4j.info("Inside DB MoveLines SQLException"+e.getMessage());
}
finally
{
try
{
ps1.close();
log4j.info("Inside movement Line Finally");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
sqlQry="INSERT INTO ad_pinstance (ad_pinstance_id, AD_CLIENT_ID, AD_ORG_ID, CREATED, CREATEDBY, UPDATED, UPDATEDBY," +
"ad_process_id, record_id, isprocessing, ad_user_id,result) VALUES " +
"(?,?,?,NOW(),?,NOW(),?,?,?,?,?,?)";
ps5 = conn.prepareStatement(sqlQry);
for(MaterialRequestIssuanceVO movementvo:mlinelist){
try{
pinstanceId = SequenceIdData.getUUID();
log4j.info("pinstanceId: "+pinstanceId);
ps5.setString(1, pinstanceId);
log4j.info("Client Id: "+movementvo.getClientid());
ps5.setString(2,movementvo.getClientid());
log4j.info("Orgid: "+movementvo.getOrgid());
ps5.setString(3,movementvo.getOrgid());
ps5.setString(4, movementvo.getCreatedby());
ps5.setString(5,movementvo.getUpdatedby());
ps5.setString(6,"122");
ps5.setString(7,issuanceId);
ps5.setString(8,"N");
ps5.setString(9,user);
ps5.setInt(10, Integer.parseInt("1"));
count=ps5.executeUpdate();
}
catch(SQLException e){
log4j.info("saveMRIssuanceMovementData Line SQLException"+e.getMessage());
}
finally
{
try
{
ps5.close();
log4j.info("Inside movement Line Finally");
} catch (SQLException e) {
e.printStackTrace();
}
}
try{
ps=conn.prepareStatement("select m_movement_post(?)");
ps.setString(1, pinstanceId);
rs = ps.executeQuery();
while(rs.next()){
log4j.info("Result Set: "+rs.getString(1));
}
}catch(SQLException e){
log4j.info("Movement Post Exception: "+e);
}
finally{
ps.close();
}
}
conn.commit();
} catch (Exception e) {
try {
conn.rollback();
count = 0;
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//Above Mensined Exception Catching hear
log4j.info("Inside DB saveMRIssuanceMovementData Line SQLException"+e.getMessage());
}
finally
{
try
{
if(conn != null)
conn.close();
}
catch(SQLException e)
{
}
}
return count;
}
PreparedStatement is closed
You can get this exception when you're trying to (re)use a PreparedStatement while it has been closed. Check the line number of the first line in the stacktrace. It should hint which PreparedStatement it is talking about. Then backtrack its use in the code and fix code accordingly.
Judging the flood of code you've posted, I suspect that it's the ps5 which is been created before a for loop and been closed inside the for loop. Here's an extract of relevance from your code:
ps5 = conn.prepareStatement(sqlQry);
for (MaterialRequestIssuanceVO movementvo : mlinelist) {
try {
ps5.setString(1, string);
ps5.executeUpdate();
} finally {
ps5.close(); // You're closing inside the loop!
}
}
The next iteration in the loop won't be able to reuse the same PreparedStatement anymore. The fix is obvious: close it after completion of the for loop.
try {
ps5 = conn.prepareStatement(sqlQry);
for (MaterialRequestIssuanceVO movementvo : mlinelist) {
ps5.setString(1, string);
ps5.executeUpdate();
}
} finally {
ps5.close();
}
That said, logging all exceptions as Info or doing only e.printStackTrace() and suppressing them and continuing the code flow isn't always a good idea. Log them as Error and then hard-throw thereafter.
} catch (Exception e) {
logger.error("Your message", e);
throw e;
}
Rethrowing isn't needed for exceptions during close, but logging them as Warn is useful.
Last but not least, consider refactoring the exceptionally large method block into separate and sensible methods (tasks) ;)

Categories