【问题标题】:java.sql.SQLException: database connection closedjava.sql.SQLException:数据库连接关闭
【发布时间】:2017-07-18 13:31:56
【问题描述】:

我对 Java (JDBC) 的 SQLite 驱动程序有疑问。当我想加载一个数据库时,它说它已加载,但它立即关闭了。我将代码分隔在不同的文件中:

SQLite.java

package net.jeddsan;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;

public class SQLite {
    public static Connection createOrOpenDatabase(String database) {

        String url = "jdbc:sqlite:" + database;

        try (Connection conn = DriverManager.getConnection(url)) {
            if (conn != null) {
                System.out.println("A new database has been created.");
                conn.setAutoCommit(false);
                return conn;
            }else{
                return null;
            }

        } catch (SQLException e) {
            System.out.println(e.getMessage());
            return null;
        }
    }
}

MainController.java

@Override
    public void initialize(URL url, ResourceBundle rb) {
        c = SQLite.createOrOpenDatabase("test.db");

        try {
            sta = c.createStatement();
            sta.executeQuery("INSERT INTO token (token) VALUES ('123')");
            sta.close();
        } catch (SQLException ex) {
            Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            c.close();
        } catch (SQLException ex) {
            Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

日志

SCHWERWIEGEND: null
java.sql.SQLException: database connection closed
    at org.sqlite.core.CoreConnection.checkOpen(CoreConnection.java:336)
    at org.sqlite.jdbc4.JDBC4Connection.createStatement(JDBC4Connection.java:38)
    at org.sqlite.jdbc3.JDBC3Connection.createStatement(JDBC3Connection.java:193)
    at net.jeddsan.MainController.initialize(MainController.java:103)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
    at net.jeddsan.koradesktop.start(koradesktop.java:22)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:745)

【问题讨论】:

  • MainController.java中的103是哪一行?
  • 103: sta = c.createStatement();你可以在代码中看到它。
  • 与您的问题无关,但有一些建议:在您的 initialize 方法中,不要将连接分配给实例字段,而是分配给局部变量,并使用 try-with-resources而不是带有close() 的手写finally-block。从长远来看,使用实例字段进行连接只会给您带来痛苦。

标签: java sql sqlite jdbc


【解决方案1】:

当您离开其作用域时,此 try-with-resources 构造将在 Connection 上调用方法 close

try (Connection conn = DriverManager.getConnection(url)) {
    return conn;
}

所以,你有效地返回了关闭的连接。

将其更改为常规 try 构造以返回实时连接:

try {
    Connection conn = DriverManager.getConnection(url);
    return conn;
} catch (SQLException e) {
    return null;
}

【讨论】:

  • 非常感谢。这就是解决方案。
  • 完全删除 try-catch 并在方法中添加 throws SQLException 可能会更好。这将使您免于不清楚NullPointerExceptions,并且在对该连接执行查询时无论如何都需要处理SQLException
猜你喜欢
  • 2016-06-04
  • 2015-11-03
  • 1970-01-01
  • 1970-01-01
  • 2014-09-19
  • 1970-01-01
  • 2016-07-01
  • 2011-08-02
相关资源
最近更新 更多