• Wir präsentieren Dir heute ein Stellenangebot für einen Java Entwickler - m/w/d in Augsburg, München, Stuttgart oder Bamberg. Hier geht es zur Jobanzeige

java.sql Statement kann nicht geschlossen werden

C

Carcharoth

Bekanntes Mitglied
Guten Tag

Ich brüte jetzt schon eine ganze Weile über einen kleinen Fehler in meinem Code.
Wenn ich den Code so ausführe, bekomme ich eine Fehlermeldung
Java:
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::4.0.4 statement is closed
.

Kommentiere ich die Zeile 51 in der Methode executeSQL - statement.close() - aus, läuft es prima.
Für mich ist das nicht logisch denn ich brauche ja das Statement nicht mehr wenn das Resultat im ResultSet gespeichert ist.
Zusätzlich hatte ich vorher die gleiche Klasse mit HSQLDB anstatt mit UCANACCESS so am laufen, und da war es kein Problem.

Ich frage mich:
a) wieso das statement nicht geschlossen werden darf ?
b) was passiert wenn ich es einfach nicht schliesse? erledigt das der Garbage Collector?

Java:
import java.sql.*;

// <dependency>
//     <groupId>net.sf.ucanaccess</groupId>
//     <artifactId>ucanaccess</artifactId>
//     <version>4.0.4</version>
// </dependency>

public class Accdb {

    private Connection con;               
    private String path;               
    private String user;               
    private String password;           
    private String tableName;           

    // Konstruktor
    Accdb(String path, String user, String password, String tableName) {
        this.path = path;
        this.user = user;
        this.password = password;
        this.tableName = tableName;

        try{
            con = DriverManager.getConnection("jdbc:ucanaccess://" + path, user, password);
        }catch(SQLException se){
            se.printStackTrace();
        }
    }

    // Schliessen der Connection
    public void closeConnection() {
        try {
            con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // Ausführen des Query
    public ResultSet executeSQL(String sql) {
        Statement statement=null;
        ResultSet res=null;

        try {
            statement = con.createStatement(
                    ResultSet.TYPE_SCROLL_INSENSITIVE,
                    ResultSet.CONCUR_READ_ONLY);

            res = statement.executeQuery(sql);
            statement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return res;
    }

    // Lesen aller Einträge der DB und Ausgabe über die Konsole
    public void readDB() {
        try {
            ResultSet res = executeSQL("SELECT * FROM " + tableName);

            if (res.next()) {
//                res.last();
//                System.out.println("Total rows is : " + res.getRow() + "\n");
//
//                res.beforeFirst();

                int columnCount = res.getMetaData().getColumnCount();
                int rowNumber=1;
                while (res.next()) {
                    System.out.print(rowNumber + ":  ");
                    for (int i = 1;i<=columnCount;i++ ) {
                        if (i!=columnCount) {
                            System.out.print(res.getString(i) + ", ");
                        } else System.out.print(res.getString(i));
                    }
                    System.out.println();
                    rowNumber++;
                }
            } else {
                System.out.println("No Data");
            }

            res.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Accdb accdb = new Accdb("H:\\Database.accdb", "","","Data");
        System.out.println("DB is open.");
        System.out.println("------------------------------------------------------------------------------------------------");

        accdb.readDB();

        accdb.closeConnection();
        System.out.println("------------------------------------------------------------------------------------------------");
        System.out.println("DB has been closed !");
    }
}
 
kneitzel

kneitzel

Top Contributor
Also im Augenblick kann ich das noch nicht ganz nachvollziehen, dass in Zeile 51 die Exception kommt. Ich würde die Exception in readDB erwarten.

Das Statement solltest Du erst schließen, wenn auch das ResultSet verarbeitet ist. Das Statement zu schließen um dann das ResultSet zu verarbeiten, wird so nicht funktionieren.

Üblich ist:
a) try with resources - Es wird also nicht selbst close aufgerufen sondern das macht das try with resources für dich.
b) Innerhalb des try blocks erfolgt auch die Verarbeitung des ResultSets.

Wenn Du das anders machen möchtest, dann geht das natürlich auch. Dazu hat das Statement ein closeOnCompletion Aufruf.
Dann wird das Statement erst mit dem schließen des ResultSets geschlossen.

Aber:
Das close gehört dann generell in ein finally:

Also das Pattern für manuelles schließen ist immer sowas wie:

Java:
Statement statement;
try {
    statement = ....;
} finally {
    if (statement != null) statement.close();
}

Wobei ich da dann gerne eine Methode safeClose(Closable) hatte, die halt die Prüfung gemacht hat und Exceptions gefangen und ignoriert hat.
Aber: Es gibt das try with resources und das sollte man nutzen!
 
C

Carcharoth

Bekanntes Mitglied
Danke.

Das Statement solltest Du erst schließen, wenn auch das ResultSet verarbeitet ist. Das Statement zu schließen um dann das ResultSet zu verarbeiten, wird so nicht funktionieren.
Diese Erkenntnis hilft schon weiter.

Ich versuch mich mal ans Try with resources.
 
VfL_Freak

VfL_Freak

Top Contributor
bedeutet die meldung nicht ganz simpel, dass das Statement an dem Punkt bereits geschlossen ist ??
 
kneitzel

kneitzel

Top Contributor
bedeutet die meldung nicht ganz simpel, dass das Statement an dem Punkt bereits geschlossen ist ??
Ja, genau. Und die Exception kommt vermutlich beim Zugriff auf das ResultSet. Das erfordert eine offenes Statement. Daher läuft es durch, wenn das Statement nicht geschlossen wird. Das Ergebnis wird in der Regel ausgewertet, ehe man das Statement schließt. (So kenne ich das eigentlich nur) Oder eben die Alternative: closeOnCompletion - dann wird es geschlossen, wenn das ResultSet geschlossen wird.
 
C

Carcharoth

Bekanntes Mitglied
Ich habe die Methode executeSQL wie folgt umgeschrieben (mit einem Try with Resources).
Ich musste leider im Catch das null zurückgeben, da Java sonst meckert, dass der return fehlt.

Java:
public ResultSet executeSQL(String sql) {
        try (ResultSet res = con.createStatement(
                    ResultSet.TYPE_SCROLL_INSENSITIVE,
                    ResultSet.CONCUR_READ_ONLY).executeQuery(sql)) {
            return res;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

Nachdem ich in der Methode readDB den obengenannten Code aufrufe
Java:
ResultSet res = executeSQL("SELECT * FROM " + tableName);

führt der erste Zugriff auf res.next() zu einem Fehler "invalid cursor state: identified cursor is not open".
 
F

fhoffmann

Top Contributor
Du solltest die Idee vergessen, ein ResultSet zurückzugeben.
Sobald das Statement geschlossen ist, kann das ResultSet nicht mehr benutzt werden.

Der Grund ist folgender:
Es ist denkbar, dass das ResultSet am Anfang noch nicht alle Zeilen enthält (sondern beispielsweise nur die ersten 50 Zeilen). Erst wenn du mit resultSet.next() weitere Zeilen abfragst, werden diese von der Datenbank geholt. Und das geht nur, wenn das Statement noch offen ist.

Wenn du dazu mehr wissen willst, suche einmal nach "Datenbank Cursor".
 
C

Carcharoth

Bekanntes Mitglied
OK das leuchtet mir ein mit deinem Beispiel.
Was ist aber dann die Alternative? gleich beim lesen des Resultsets die Daten in eine andere Datenstrutkur transferieren und diese zurückgeben?
 
kneitzel

kneitzel

Top Contributor
Du solltest den Code nicht so strukturiewren - das ist das, was ich mit
nnerhalb des try blocks erfolgt auch die Verarbeitung des ResultSets.
meinte.

Also so ein typischer Aufbau wäre bei Dir einfach ein:

Java:
    public void readDB() {
        try (Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
             ResultSet res = stmt.executeQuery(sql)) {
            
            while (res.next()) {
               // Zeile verarbeiten
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Packages erstellen mit Java-Editor Java Basics - Anfänger-Themen 6
mr.kottig Großeltern herausfinden Java - Map? Java Basics - Anfänger-Themen 16
L Java erstellt leere Datei Java Basics - Anfänger-Themen 8
D Java Übungsaufgaben Java Basics - Anfänger-Themen 6
A Standardabweichung in Java berechnen Java Basics - Anfänger-Themen 10
H Java fx Java Basics - Anfänger-Themen 3
J JAVA-Problem blockiert MEDIATHEKVIEW Java Basics - Anfänger-Themen 13
M Java Anfang Java Basics - Anfänger-Themen 13
D Java Thread wartet nur ein mal Java Basics - Anfänger-Themen 1
D Java Thread wartet nur ein mal Java Basics - Anfänger-Themen 0
I Java auf der Konsole Java Basics - Anfänger-Themen 5
T Die neuste Java jee Java Basics - Anfänger-Themen 12
Spandeli8 Erzeugte Objekte gegenüber Bildern hervorheben in Java Processing Java Basics - Anfänger-Themen 1
G Java Hilfe Java Basics - Anfänger-Themen 3
johnboyne Java Zeichen Trennen Java Basics - Anfänger-Themen 1
I Java Quicksort PAP Java Basics - Anfänger-Themen 2
K Buchstabenzähler Java (Anfänger) Java Basics - Anfänger-Themen 35
J Java List, Bitte um Hilfe Java Basics - Anfänger-Themen 15
J Java List, bitte um Hilfe Java Basics - Anfänger-Themen 3
E Kleines Java-Projekt für Anfänger Java Basics - Anfänger-Themen 10
A Schleifen in Java Java Basics - Anfänger-Themen 4
Alan6 Java Editor BMI Rechner Java Basics - Anfänger-Themen 7
A Java die richtige Programmiersprache für mein Projekt? Java Basics - Anfänger-Themen 1
P myClass?.method() in Java Java Basics - Anfänger-Themen 4
I Java String einlesen und auslesen Java Basics - Anfänger-Themen 11
Marc111111111 Selection Sort in Java?? Java Basics - Anfänger-Themen 6
NicoDeluxe Java RAM Management Java Basics - Anfänger-Themen 26
N Groß- und Kleinschreibung bei Java: void Methode Java Basics - Anfänger-Themen 1
T SelectionSort Java Java Basics - Anfänger-Themen 1
TimoN11 Frage zu Java-Vererbung (Cast) Java Basics - Anfänger-Themen 5
T Java Fx Java Basics - Anfänger-Themen 4
J Alle .java Dateien von einem Verzeichnis in eine Zip speichern Java Basics - Anfänger-Themen 2
O Exception in thread "main" java.lang.ArithmeticException: / by zero Java Basics - Anfänger-Themen 4
G Java Rabatt berechnen Java Basics - Anfänger-Themen 8
MPFeuer JAVA Expert-PDF Java Basics - Anfänger-Themen 1
M Java-Applet zur Mittelwertberechnung Java Basics - Anfänger-Themen 3
Abraham42 Berechnung der Kühlung Java Java Basics - Anfänger-Themen 12
J Java Queue mit default Werten erstellen Java Basics - Anfänger-Themen 4
F Erste Schritte java.util.Scanner: Beliebig langen Text per Paste in Console eingeben ? Java Basics - Anfänger-Themen 14
S Allgemeine Java Codes lesen und verstehen Java Basics - Anfänger-Themen 7
TimoN11 Mail Programm mit Java? Java Basics - Anfänger-Themen 1
TimoN11 Java spezielle Suchprobleme - Aufgabe Java Basics - Anfänger-Themen 5
I Java-Wort einlesen und ausgeben Java Basics - Anfänger-Themen 7
H Brauche Hilfe in Java Eclipse Programmieraufgabe Neuling Java Basics - Anfänger-Themen 3
JaVaN0oB java.lang.ArrayIndexOutOfBoundsException Java Basics - Anfänger-Themen 17
Abraham42 Sparguthaben JAVA Java Basics - Anfänger-Themen 4
TimoN11 Java Klassen Global einbinden Java Basics - Anfänger-Themen 1
H Binominalkoeffizient tail-rekursiv in java darstellen Java Basics - Anfänger-Themen 0
H Audio in Java Java Basics - Anfänger-Themen 3
I Erklärung zum Java Code Java Basics - Anfänger-Themen 2
AlexVo String zu Java Anweisung getString("*** java code ***") Java Basics - Anfänger-Themen 19
R Java (Eclipse) "Lagerverwaltung" HILFE Java Basics - Anfänger-Themen 13
TimoN11 Java - Eine oder mehrere Eingaben möglich machen Java Basics - Anfänger-Themen 6
M Rekursive Java-Methode Java Basics - Anfänger-Themen 13
M Java Spiel wie Wer wird Millionär Java Basics - Anfänger-Themen 1
bafou Dreieckszahlen in java Java Basics - Anfänger-Themen 3
P Best Practice Druck aus Java Anwendung in MacOs Java Basics - Anfänger-Themen 0
G Java 2-dimensionalen int-Array Summe Java Basics - Anfänger-Themen 2
B java.time Duration mit Kommazahl? Java Basics - Anfänger-Themen 4
Devin Wo kann man einen Java Lehrplan finden? Java Basics - Anfänger-Themen 5
KogoroMori21 Java Datum Differenz (kleiner Fehler) Java Basics - Anfänger-Themen 10
O Java Weinachtsbaum in einem Bilderramen Java Basics - Anfänger-Themen 5
F Java Programm, das kleine Buchstaben in einem String zählen soll und bei großen Buchstaben oder Sonderzeichen abbrechen soll. Java Basics - Anfänger-Themen 5
Gaudimagspam Dringend Java Hilfe benötigt Java Basics - Anfänger-Themen 19
M Java Kompilieren über Package grenzen hinaus Java Basics - Anfänger-Themen 4
N java.util.InputMismatchException Fehler Java Scanner Java Basics - Anfänger-Themen 1
Gaudimagspam BMI in Java implementieren Java Basics - Anfänger-Themen 38
C Was ist nötig für ein Java-Programm auf Server für Website Java Basics - Anfänger-Themen 18
F Fehlermeldung java.lang.NullPointerException Java Basics - Anfänger-Themen 4
S Sprung mit Java (GameGrid) Java Basics - Anfänger-Themen 9
Devin Wie lange braucht man um Java zu beherrschen und wie kann man es am schnellsten erlernen? Java Basics - Anfänger-Themen 7
G Java Klassen und Instanzmethoden Java Basics - Anfänger-Themen 15
Zrebna Frage zum "Referenzen-konzept" in Java Java Basics - Anfänger-Themen 8
C java.util Timer läuft zu langsam? Java Basics - Anfänger-Themen 1
T Klassendiagramm in Java überführen Java Basics - Anfänger-Themen 2
Gaudimagspam Caesars Code entziffern in Java Java Basics - Anfänger-Themen 8
V Gehalt berechnen in Java Java Basics - Anfänger-Themen 6
java3690 Java- liste füllen ud die werte addieren Java Basics - Anfänger-Themen 13
justemii Gehalt berechnen - Aufgabe Java-Programm Java Basics - Anfänger-Themen 9
P Mit iPad Java lernen Java Basics - Anfänger-Themen 15
W Java in Exe Datei umgewandelt, Ressourcen fehlen (Bilder und Audiodateien) Java Basics - Anfänger-Themen 1
N Best Practice How can I creat a programm with java under windows 10 in order to open an spreadsheet in libreoffice calc format Java Basics - Anfänger-Themen 11
T Start-Activity für Java Maven Web-Anwendung festlegen Java Basics - Anfänger-Themen 2
J Java FX - Label aktualisieren Java Basics - Anfänger-Themen 1
A Hilfe bei Java Projekt Java Basics - Anfänger-Themen 4
G Java Bruchrechner Addition, Multiplikation... Java Basics - Anfänger-Themen 12
M Java Einstellung von Apache POI für MS Word Erstellung mit Eclipse Java Basics - Anfänger-Themen 6
B Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException Java Basics - Anfänger-Themen 8
T Java Swing - Dreieck zeichnen mit verschiedenen Variablen Java Basics - Anfänger-Themen 8
P Wie für EIN Java Programm von 64bit Java (=Standard) auf 32bit Java Installation (Windows) umschalten? Java Basics - Anfänger-Themen 6
C Suche Nachhilfe in Java Java Basics - Anfänger-Themen 5
B java.io.OutputStream zu java.io.InputStream konvertieren Java Basics - Anfänger-Themen 18
A Scanner Befehl Java Anfänger Java Basics - Anfänger-Themen 8
M Java entity und wertklassen Java Basics - Anfänger-Themen 2
G Java Vererbung Java Basics - Anfänger-Themen 8
M Java Klasse Object Java Basics - Anfänger-Themen 5
M Java GUI label ändert sich erst zum Schluss Java Basics - Anfänger-Themen 4
G Java Lambda Ausdrücke Java Basics - Anfänger-Themen 19
M Java GUI explorer aufrufen um Pfad zu bekommen Java Basics - Anfänger-Themen 3
M Java Anweisungen Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Anzeige

Neue Themen


Oben