#java #mysql #exception
#java #mysql #исключение
Вопрос:
У меня есть эта функция Java, которая запускается и выдает ошибку. Я не могу понять, почему это происходит, потому что это первая функция в программе для запуска, поэтому никакие другие соединения, операторы или наборы результатов не были открыты. Ошибка
Operation not allowed after ResultSet closed
java.sql.SQLException: Operation not allowed after ResultSet closed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:768)
at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:7008)
at equipmentinventoryimporter.Importer.sqlTable(Importer.java:219)
at equipmentinventoryimporter.Importer.main(Importer.java:58)
и функция
private static void sqlTable(SQLTableJob sqltableJob) {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection connMySQL2 = null;
Statement stntMySQL2 = null;
try {
connMySQL2 = DriverManager.getConnection(mysqlAddress, mysqlUsername, mysqlPassword);
stntMySQL2 = connMySQL2.createStatement();
//MySQL Transaction
System.out.println("Starting " sqltableJob.getMysqlTable() " transaction");
stntMySQL2.execute("START TRANSACTION");
String insertQuery = "";
try {
final String inactiveQuery = "UPDATE `" sqltableJob.getMysqlSchema() "`.`" sqltableJob.getMysqlTable() "` SET `active`=0";
stntMySQL2.executeUpdate(inactiveQuery);
final ResultSet rs2 = stntMySQL2.executeQuery(sqltableJob.getSQLSelectQuery());
int counter = 0;
while (rs2.next()) {
counter ;
final String mysqlSetClause = sqltableJob.getMysqlSetClause(rs2);
insertQuery = "INSERT INTO `" sqltableJob.getMysqlSchema() "`.`" sqltableJob.getMysqlTable() "` SET "
mysqlSetClause
" ON DUPLICATE KEY UPDATE "
mysqlSetClause;
stntMySQL2.executeUpdate(insertQuery);
if (counter % 5000 == 0) {
System.out.println("Processed " counter " rows.");
}
}
rs2.close();
if (!sqltableJob.isKeepInactives()) {
final String deleteQuery = "DELETE FROM `" sqltableJob.getMysqlSchema() "`.`" sqltableJob.getMysqlTable() "`"
"WHERE `active`=0";
stntMySQL2.executeUpdate(deleteQuery);
}
stntMySQL2.execute("COMMIT");//last line of try block
System.out.println("Committed " sqltableJob.getMysqlTable() " transaction");
} catch (Exception ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
System.out.println("Transaction level exception thrown.");
System.out.println(insertQuery);
stntMySQL2.execute("ROLLBACK");
System.out.println("MySQL query rolled back.");
}
//Another MySQL Transaction goes here
} catch (Exception ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
System.out.println("Connection level exception thrown.");
} finally {
if (stntMySQL2 != null) {
try {
stntMySQL2.close();
} catch (Exception ex) {
}
}
if (connMySQL2 != null) {
try {
connMySQL2.close();
} catch (Exception ex) {
}
}
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
System.out.println("Program level exception thrown.");
}
}
SQLTableJob — это
package equipmentinventoryimporter;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
*
* @author jmgreen
*/
public interface SQLTableJob {
public String getMysqlSchema();
public String getMysqlTable();
public String getSQLSelectQuery();
public String getMysqlSetClause(ResultSet rs) throws SQLException;
public boolean isKeepInactives();
}
и конкретный SQLTableJob, на который ссылаются, является
public class SQLTableJob10I implements SQLTableJob{
public boolean isKeepInactives() {
return true;
}
public String getMysqlSchema() {
return "Temp_Equipment_Inventory";
}
public String getMysqlTable() {
return "PC_Combined";
}
public String getSQLSelectQuery() {
final String sqlSelectQuery = "SELECT *"
" FROM Temp_Equipment_Inventory.PC_Table10i";
return sqlSelectQuery;
}
public String getMysqlSetClause(ResultSet rs) throws SQLException {
final String mysqlSetClause =
"`Account_No`=" Importer.sqlChar(rs.getString("Account_No"))
",`Inventory_No`=" Importer.sqlChar(rs.getString("Inventory_No"))
",`Building_No`=" Importer.sqlChar(rs.getString("Building_No"))
",`Location`=" Importer.sqlChar(rs.getString("Location"))
",`FYYR_No`=" Importer.sqlChar(rs.getString("FYYR_No"))
",`Cost`=" Importer.sqlChar(rs.getString("Cost"))
",`Name`=" Importer.sqlChar(rs.getString("Name"))
",`Desc1`= ''"
",`Desc2`= ''"
",`Desc3`= ''"
",`CDCATY`=" Importer.sqlChar(rs.getString("CDCATY"))
",`CDSRCE`=" Importer.sqlChar(rs.getString("CDSRCE"))
",`FLDCAL`=" Importer.sqlChar(rs.getString("FLDCAL"))
",`CDACQN`=" Importer.sqlChar(rs.getString("CDACQN"))
",`FLOWNR`=" Importer.sqlChar(rs.getString("FLOWNR"))
",`FLSHAR`=" Importer.sqlChar(rs.getString("FLSHAR"))
",`CDDELT`=" Importer.sqlChar(rs.getString("CDDELT"))
",`CNYTDT`=" Importer.sqlChar(rs.getString("CNYTDT"))
",`NOPURO`=" Importer.sqlChar(rs.getString("NOPURO"))
",`NOPIMO`=" Importer.sqlChar(rs.getString("NOPIMO"))
",`CDPREI`=" Importer.sqlChar(rs.getString("CDPREI"))
",`Original_Amount`=" Importer.sqlChar(rs.getString("Original_Amount"))
",`Serial_Code`=" Importer.sqlChar(rs.getString("Serial_Code"))
",`CDCOMP`=" Importer.sqlChar(rs.getString("CDCOMP"))
",`NOCHECK`=" Importer.sqlChar(rs.getString("NOCHECK"))
",`CDCOMM`=" Importer.sqlChar(rs.getString("CDCOMM"))
",`Last_Update`=" Importer.sqlDate(rs.getString("Last_Update"))
",`CDDEPT`=" Importer.sqlChar(rs.getString("CDDEPT"))
",`Room_No`=" Importer.sqlChar(rs.getString("Room_No"))
",`Date_Scanned`=" Importer.sqlDate(rs.getString("Date_Scanned"))
",`Date_Acquired`=" Importer.sqlDate(rs.getString("Date_Acquired"))
",`Manufacturer_Name`=" Importer.sqlChar(rs.getString("Manufacturer_Name"))
",`Expiry_Date`=" Importer.sqlDate(rs.getString("Expiry_Date"))
",`Active`='1'";
return mysqlSetClause;
}
}
Комментарии:
1. Не могли бы вы предоставить содержимое файла SQLTableJob.java ?
2. проверьте исходное сообщение на наличие запрошенных изменений.
Ответ №1:
Из Javadoc:
ResultSet
Объект автоматически закрывается, когдаStatement
объект, который его сгенерировал, закрывается, выполняется повторно или используется для получения следующего результата из последовательности нескольких результатов.
Из вашего кода:
stntMySQL2.executeUpdate(inactiveQuery);
final ResultSet rs2 = stntMySQL2.executeQuery(sqltableJob.getSQLSelectQuery());
while (rs2.next()) {
...
stntMySQL2.executeUpdate(insertQuery);
Вы повторно выполняете stntMySQL2
внутри цикла. Это автоматически закрывается rs2
.
Для исправления используйте другой объект statement внутри цикла.
Комментарии:
1. Также обратите внимание, что закрытие a
Connection
автоматически закроет всеStatement
экземпляры, которые были созданы из него. Этого нет в JavaDoc, но спецификация JDBC требует этого. Недавно обнаружил это с помощью другого вопроса.