当我开始在标题中,当我在我的java应用程序中查询用户数据时,我收到以下消息:“ResultSet关闭后不允许操作”。
我知道如果您尝试同时打开更多ResultSet,就会发生这种情况。
这是我目前的代码:
App调用getProject(“...”),其他2种方法只是为了帮助。我正在使用2个类,因为有更多的代码,这只是我得到的异常的一个例子。
请注意我已经翻译了变量名等,以便更好地理解,我希望我没有错过任何内容。
/* 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 */
在构造函数中添加两个类的语句,在构造每个类时调用connection.getStatement()。
tProject和tProject_User是我的枚举,我用它来简化名称处理。 generateSelect是我的方法,应该按预期工作。我正在使用它,因为在我编写了大部分代码后,我发现了有关预处理语句的内容,因此我将其保留原样。
我正在使用最新的java MySQL连接器(5.1.21)。
我不知道还有什么可以尝试的。任何建议将不胜感激。
答案 0 :(得分:5)
如果没有看到你的代码,真的不可能肯定地说出了什么问题。但请注意,在很多情况下ResultSet
会自动关闭。引用official documentation:
当Statement对象时,ResultSet对象自动关闭 生成它的是关闭,重新执行或用于检索下一个 由多个结果序列产生。
可能你有其中一件事正在发生。或者你在实际完成它之前明确地关闭了ResultSet
。
另外,您是否考虑过使用像Hibernate这样的ORM框架?通常情况下,比低级JDBC API更令人愉快。
答案 1 :(得分:5)
引用@ aroth的回答:
在许多情况下,ResultSet
会自动关闭。引用官方文档:
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.
在您的代码中,您正在方法ResultSet
中使用相同的getUser
对象创建新的Statement
,该对象在usersInProject
方法中创建了结果集,从而导致关闭方法usersInProject
中的结果集对象。
<强>解决方案:强>
创建另一个语句对象并在getUser
中使用它来创建结果集。