【问题标题】:ResultSet closed exception while in the middle of while next() loopResultSet 在 while next() 循环中间关闭异常
【发布时间】:2016-04-15 13:27:05
【问题描述】:

我知道人们以前遇到过这个异常,主要是因为:

  • next() 未被调用
  • ResultSet 或连接在完成任务之前已关闭

这似乎不是我的情况。

我使用 preparedstatement 进行查询,并在 while 循环中调用 rs.next()

发生的情况是我在 while 循环中得到异常。并且它不会在任何特定行给我例外,它每次都会改变(我无法检测到模式)。

我在此堆栈跟踪中显示此错误:

java.sql.SQLException: ResultSet closed
at org.sqlite.core.CoreResultSet.checkOpen(CoreResultSet.java:69)
at org.sqlite.jdbc3.JDBC3ResultSet.findColumn(JDBC3ResultSet.java:38)
at org.sqlite.jdbc3.JDBC3ResultSet.getString(JDBC3ResultSet.java:437)
at music.store.DBHelper.queryAnything(DBHelper.java:175)
at music.store.Search.doPost(Search.java:45)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

这是我正在运行的一段代码

public ArrayList<Album> queryAnything(String query) throws SQLException {
    ArrayList<Album> albums = new ArrayList<>();
    PreparedStatement statement = null;
    Connection conn = null;

    try { 
        Class.forName("org.sqlite.JDBC");
        conn = DriverManager.getConnection("jdbc:sqlite:" + _dbPath);

        statement = conn.prepareStatement("SELECT "
                + "s.id as sid, " 
                + "s.title as songTitle, "
                + "s.price,"
                + "a.id as aid,"
                + "a.title as albumTitle,"
                + "a.artist,"
                + "a.publisher,"
                + "a.year,"
                + "a.genre "
                + "FROM song s JOIN album a ON s.aid = a.id WHERE s.title = ? OR a.title = ? OR a.artist = ?;");
        statement.setString(1, query);
        statement.setString(2, query);
        statement.setString(3, query);
        ResultSet rs = statement.executeQuery();

        Song song = null;
        Album album = null;
        while (rs.next()) {
            album = new Album(rs.getString("aid"), 
                              rs.getString("artist"), 
                              rs.getString("albumTitle"), 
                              rs.getString("genre"), 
                              rs.getString("publisher"), 
                              rs.getInt("year"));

            song = new Song(rs.getString("sid"), 
                            rs.getString("aid"),
                            rs.getString("songTitle"),
                            rs.getString("artist"),
                            rs.getString("albumTitle"),
                            rs.getFloat("price"));


            if (!albums.contains(album)) {
                albums.add(album);
            }

            album.set_songList(song);
        } 
    } catch (Exception e) { 
        e.printStackTrace(); 
    } finally {
        if (statement != null) statement.close();
        if (conn != null) conn.close();
    }

    return albums;
}

感谢您的帮助 唐

【问题讨论】:

  • 您似乎不止一次地从结果集中获取了一些列。当直接使用 JDBC 时,最好只获取一次值,并按照它们在 SQL 中声明的顺序。我什至会通过索引而不是名称来引用列。尝试先在变量中分配所有值,然后在构造函数调用中使用变量。
  • 没错。有用。你可以让它成为一个答案,我会标记它。谢谢,伙计
  • 很高兴能帮上忙! :)

标签: java jdbc sqlite


【解决方案1】:

来自@vagelis 的回答:

您似乎不止一次地从结果集中获取了一些列。当直接使用 JDBC 时,最好只获取一次值,并按照它们在 SQL 中声明的顺序。我什至会通过索引而不是名称来引用列。尝试先在变量中分配所有值,然后在构造函数调用中使用变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 1970-01-01
    相关资源
    最近更新 更多