hsqldb

zerix

Hausmeister
Moderator
Guten Morgen.
Ich habe mir mit hsqldb einige Tabellen angelegt und möchte Daten darin speichern. Wenn ich mit dem DatabaseManager der bei hsqldb dabei ist die Tabellen befülle werden die Daten darin gespeichert. Wenn ich jedoch mit meinem Java-Programm Daten darin speichern will, klappt es nicht. Ich kann mit meinem Programm die Daten abrufen die ich geändert/hinzugefügt habe und die Daten die noch drin stehen, aber sobald das Programm beendet ist, sind die Änderungen wieder verworfen. Ich weiß, dass hsqldb in einem In-Memory-Mode laufen kann, aber ich habe als URL eine Datei angegeben und dann sollte das eigentlich nicht so sein. Wäre für Hilfe sehr dankbar.

MFG zerix
 
Hallo,

damit die Veränderungen einer hsqldb Persistent gemacht werden musst du zum einen mal Commit nach einem Insert/Update aufrufen und zum anderen musst du die Datenbank beim schließend der letzten Connection explizit mit SHUTDOWN herunterfahren, andernfalls werden die gemachten Änderungen nicht persistent gemacht. Über das Connection Property shutdown=true kann man die HSQLDB dazu veranlassen beim schließen der letzten Datenbankverbindung automatisch ein SHUTDOWN durchzuführen.

Schau mal hier:
Java:
/**
 * 
 */
package de.tutorials;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;

/**
 * @author Tom
 * 
 */
public class HsqlDBExample {

    static {
        try {
            Class.forName("org.hsqldb.jdbcDriver");
        } catch (ClassNotFoundException e) {
            throw new Error(e);
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        Connection connection = DriverManager.getConnection(
                "jdbc:hsqldb:file:c:/test.db;shutdown=true", "sa", "");

        // // Step 1
        // connection.createStatement().execute(
        // "create table data(id int, value varchar(32))");
        //
        // // Step2
        // PreparedStatement preparedStatement = connection
        // .prepareStatement("INSERT INTO data VALUES(?,?)");
        // preparedStatement.setInt(1, 1);
        // preparedStatement.setString(2, "Foo");
        // preparedStatement.execute();
        //
        // preparedStatement.setInt(1, 2);
        // preparedStatement.setString(2, "Bar");
        // preparedStatement.execute();
        // preparedStatement.close();
        // connection.commit();

        // Step 3
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery("SELECT * FROM data");
        ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
        int columnCount = resultSetMetaData.getColumnCount();
        while (resultSet.next()) {
            for (int i = 1; i <= columnCount; i++) {
                System.out.print(resultSet.getString(i) + " ");
            }
            System.out.println();
        }
        resultSet.close();
        statement.close();

        connection.close();
    }
}

Ausgabe:
Code:
1 Foo 
2 Bar

Gruß Tom
 
Hallo Tom,
ich konnte das leider heute erst ausprobieren. Es funktioniert leider nicht. Die Daten werden nur zur Laufzeit des Programms in der Datenbank gespeichert. Die Daten werden nur abgespeichert, wenn ich die Datenbank als Server laufen lasse, aber das möchte ich nicht.

MFG zEriX
 
Hallo,

bist du ganz sicher das du das oben genannte Beispiel so ausprobiert hast? Bei mir funktioniert das so wie gewünscht ohne Probleme... auch nach dem neustart der Anwendung sind zuvor gespeicherte Daten noch da.

Gruß Tom
 
Das Beispiel hab ich nicht kopiert, sondern nur das was in dem Beispiel anders ist bei mir rein kopiert. Das war nur das "shutdown=true" in der URL.
Aber ich lade den Treiber nicht mit Class.forName(), sondern mit einer DataSource. Arbeite mich gerade in Spring ein und das war so als Beispiel vorgegeben. Ich hatte das ganze auf dem normalen Weg mit JDBC versucht, da hatte es nur funktioniert, wenn ich die DataSource mit close geschlossen habe. Anschließend habe ich es mit den Template-Klassen von Spring probiert. Da kann ich allerdings die DataSource nicht mit close() schließen. Und jetzt weiß ich nicht woran es liegt, dass ich erst die DataSource schließen muss, damit die Daten in die Datenbank geschrieben werden.
 
Hallo,

. Und jetzt weiß ich nicht woran es liegt, dass ich erst die DataSource schließen muss, damit die Daten in die Datenbank geschrieben werden.
Wahrscheinlich werden bei einem DataSource.close(...) auch die letzten noch offenen Datenbank Verbindungen geschlössen. Durch das shutdown=true in der URL wird beim schließen der letzten Datenbankverbindung die Datenbank heruntergefahren und der Zustand wird auf die Platte geschrieben (wie schon zuvor angemerkt...).

Gruß Tom
 
Ich habe es jetzt extra nochmal versucht.
Das hier ist jetzt meine URL zur Datenbank:
Code:
jdbc:hsqldb:file:I:/Ein...plication/DB;shutdown=true

Und sobald die Application beendet ist, ist die Änderung wieder weg, also wird nicht in die Datenbank geschrieben, aber wenn ich bevor die Anwendung beendet ist die Datenbank abfrage sind die Änderungen drin.
 
Sagt dir der Befehl CREATE MEMORY TABLE was? Ich kenne den Befehl nur ohne Memory. Dieser Befehl steht in einer Datei mit dem Namen Datenbankname.script. Kannst du damit was anfangen?
 
Hallo,

du solltest ab und an mal einen Blick in die Doku werfen...
http://hsqldb.org/web/hsqlDocsFrame.html
The three types of persistent tables are MEMORY tables, CACHED tables and TEXT tables.
Memory tables are the default type when the CREATE TABLE command is used. Their data is held entirely in memory but any change to their structure or contents is written to the <dbname>.script file. The script file is read the next time the database is opened, and the MEMORY tables are recreated with all their contents. So unlike TEMP table, the default, MEMORY tables are persistent.

Gruß Tom
 
Zurück