查询用户数据时,Java ResultSet已关闭异常

Mar*_*šak 2 java sql jdbc

当我开始在标题中,当我在我的java应用程序中查询用户数据时,我得到以下消息:"在ResultSet关闭后不允许操作".

我知道如果您尝试同时打开更多ResultSet,就会发生这种情况.

这是我目前的代码:

应用程序调用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 */
Run Code Online (Sandbox Code Playgroud)

两个类的语句都在构造函数中添加,在构造每个类时调用connection.getStatement().

tProject和tProject_User是我的枚举,我用它来更容易处理名称.generateSelect是我的方法,应该按预期工作.我正在使用它,因为在我编写了大部分代码后,我发现了有关预处理语句的内容,因此我将其保留原样.

我正在使用最新的java MySQL连接器(5.1.21).

我不知道还有什么可以尝试的.任何建议将被认真考虑.

aro*_*oth 5

没有看到你的代码,真的不可能明确地说出了什么问题.但请注意,有很多情况ResultSet自动关闭.引用官方文档:

当生成它的Statement对象关闭,重新执行或用于从多个结果序列中检索下一个结果时,ResultSet对象将自动关闭.

可能你有其中一件事正在发生.或者你在ResultSet实际完成之前明确地关闭了某个地方.

另外,您是否考虑过使用像Hibernate这样的ORM框架?一般来说,这样的东西比低级JDBC API更令人愉快.

  • @maremp - 请重读这个答案的第一句...... :-) (2认同)

Har*_*hra 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.
Run Code Online (Sandbox Code Playgroud)

在您的代码中,您正在使用ResultSet在方法中创建结果集getUser的相同Statement对象在方法中创建new ,这会导致在usersInProject方法中关闭结果集对象usersInProject.

解决方案: 创建另一个语句对象并使用它 getUser来创建结果集.