java 查询用户数据时Java ResultSet已关闭异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12335513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java ResultSet already closed exception while querying user data
提问by Marko Gre?ak
As I've started in the title, while I'm querying for user data in my java application, I get following message: "Operation not allowed after ResultSet closed".
正如我在标题中开始的那样,当我在我的 Java 应用程序中查询用户数据时,我收到以下消息:“ResultSet 关闭后不允许操作”。
I know that this is happens if you try to have more ResultSets opened at the same time.
我知道如果您尝试同时打开更多 ResultSet,就会发生这种情况。
Here is my current code:
这是我当前的代码:
App calls getProject("..."), other 2 methods are there just for help. I'm using 2 classes because there is much more code, this is just one example of exception I get.
应用程序调用 getProject("..."),其他 2 种方法仅用于帮助。我使用了 2 个类,因为有更多的代码,这只是我得到的一个异常示例。
Please note that I've translated variable names, etc. for better understanding, I hope I didn't miss anything.
请注意,为了更好的理解,我已经翻译了变量名称等,希望我没有遗漏任何内容。
/* Class which reads project data */
public Project getProject(String name) {
ResultSet result = null;
try {
// executing query for project data
// SELECT * FROM Project WHERE name=name
result = statement.executeQuery(generateSelect(tProject.tableName,
"*", tProject.name, name));
// if cursor can't move to first place,
// that means that project was not found
if (!result.first())
return null;
return user.usersInProject(new Project(result.getInt(1), result
.getString(2)));
} catch (SQLException e) {
e.printStackTrace();
return null;
} catch (BadAttributeValueExpException e) {
e.printStackTrace();
return null;
} finally {
// closing the ResultSet
try {
if (result != null)
result.close();
} catch (SQLException e) {
}
}
}
/* End of class */
/* Class which reads user data */
public Project usersInProject(Project p) {
ResultSet result = null;
try {
// executing query for users in project
// SELECT ID_User FROM Project_User WHERE ID_Project=p.getID()
result = statement.executeQuery(generateSelect(
tProject_User.tableName, tProject_User.id_user,
tProject_User.id_project, String.valueOf(p.getID())));
ArrayList<User> alUsers = new ArrayList<User>();
// looping through all results and adding them to array
while (result.next()) { // here java gets ResultSet closed exception
int id = result.getInt(1);
if (id > 0)
alUsers.add(getUser(id));
}
// if no user data was read, project from parameter is returned
// without any new user data
if (alUsers.size() == 0)
return p;
// array of users is added to the object,
// then whole object is returned
p.addUsers(alUsers.toArray(new User[alUsers.size()]));
return p;
} catch (SQLException e) {
e.printStackTrace();
return p;
} finally {
// closing the ResultSet
try {
if (result != null)
result.close();
} catch (SQLException e) {
}
}
}
public User getUser(int id) {
ResultSet result = null;
try {
// executing query for user:
// SELECT * FROM User WHERE ID=id
result = statement.executeQuery(generateSelect(tUser.tableName,
"*", tUser.id, String.valueOf(id)));
if (!result.first())
return null;
// new user is constructed (ID, username, email, password)
User usr = new user(result.getInt(1), result.getString(2),
result.getString(3), result.getString(4));
return usr;
} catch (SQLException e) {
e.printStackTrace();
return null;
} catch (BadAttributeValueExpException e) {
e.printStackTrace();
return null;
} finally {
// closing the ResultSet
try {
if (result != null)
result.close();
} catch (SQLException e) {
}
}
}
/* End of class */
Statements from both classes are added in constructor, calling connection.getStatement() when constructing each of the classes.
两个类的语句都添加到构造函数中,在构造每个类时调用 connection.getStatement()。
tProject and tProject_User are my enums, I'm using it for easier name handling. generateSelect is my method and should work as expected. I'm using this because I've found out about prepared statements after I have written most of my code, so I left it as it is.
tProject 和 tProject_User 是我的枚举,我使用它是为了更容易处理名称。generateSelect 是我的方法,应该按预期工作。我使用它是因为我在编写了大部分代码后发现了准备好的语句,所以我保持原样。
I am using latest java MySQL connector (5.1.21).
我正在使用最新的 java MySQL 连接器 (5.1.21)。
I don't know what else to try. Any advice will be appreciated.
我不知道还能尝试什么。任何建议将被认真考虑。
回答by aroth
It's not really possible to say definitively what is going wrong without seeing your code. However note that there are many situations in which a ResultSet
will be automaticallyclosed for you. To quote the official documentation:
如果没有看到您的代码,就不可能确切地说出了什么问题。但是请注意,在许多情况下,aResultSet
会自动为您关闭。引用官方文档:
A ResultSet object is automatically closed when the Statement object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
当生成它的 Statement 对象关闭、重新执行或用于从多个结果的序列中检索下一个结果时,ResultSet 对象将自动关闭。
Probably you've got one of those things happening. Or you're explicitly closing the ResultSet
somewhere before you're actually done with it.
可能你已经发生了其中一件事情。或者你在ResultSet
真正完成之前明确地关闭了某个地方。
Also, have you considered using an ORM framework like Hibernate? In general something like that is much more pleasant to work with than the low-level JDBC API.
另外,您是否考虑过使用像 Hibernate 这样的 ORM 框架?一般来说,与低级 JDBC API 相比,这样的东西使用起来要愉快得多。
回答by Hardik Mishra
Quoting from @aroth's answer:
引用@aroth 的回答:
There are many situations in which a ResultSet
will be automatically closed for you. To quote the official documentation:
http://docs.oracle.com/javase/6/docs/api/java/sql/ResultSet.html
在许多情况下,aResultSet
会自动为您关闭。引用官方文档:http:
//docs.oracle.com/javase/6/docs/api/java/sql/ResultSet.html
A ResultSet object is automatically closed when the Statement object that generated
it is closed, re-executed, or used to retrieve the next result from a sequence of
multiple results.
Here in your code , You are creating new ResultSet
in the method getUser
using the same Statement
object which created result set in the usersInProject
method which results in closing your resultset object in the method usersInProject
.
在您的代码中,您正在使用ResultSet
在方法中创建结果集getUser
的同一Statement
对象在方法中创建新对象,从而导致在usersInProject
方法中关闭您的结果集对象usersInProject
。
Solution:Create another statement object and use it in getUser
to create resultset.
解决方案:创建另一个语句对象并将其 getUser
用于创建结果集。