# hsqldb



## zerix (15. Februar 2007)

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


----------



## Thomas Darimont (15. Februar 2007)

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:

```
/**
 * 
 */
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:

```
1 Foo 
2 Bar
```

Gruß Tom


----------



## zerix (20. Februar 2007)

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


----------



## Thomas Darimont (20. Februar 2007)

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


----------



## zerix (20. Februar 2007)

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.


----------



## Thomas Darimont (20. Februar 2007)

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


----------



## zerix (20. Februar 2007)

Ich habe es jetzt extra nochmal versucht. 
Das hier ist jetzt meine URL zur Datenbank: 
	
	
	



```
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.


----------



## Thomas Darimont (20. Februar 2007)

Hallo,

versuch doch einfach mal beim schließen deiner Anwendung manuell ein "SHUTDOWN" gegen die Datenbank abzusetzen.

Gruß Tom


----------



## zerix (20. Februar 2007)

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?


----------



## Thomas Darimont (20. Februar 2007)

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


----------



## zerix (20. Februar 2007)

Ok, jetzt weiß ich wofür die Scriptdatei ist. Wenn ich die Datenbank im Server-Mode starte, dann wird die Scriptdatei immer wieder aktualisiert, aber wenn ich im Standalone-Mode bin, wird sie nicht mehr verändert. Obwohl das eigentlich geschehen sollte.


----------



## hansatwebde (27. Dezember 2008)

Ich weiß, dass der Thread schon uralt ist...
Aber wenn jemand wie ich mal nach der Lösung für das Problem sucht sollte er sie hier wenigstens finden:
Man muss in der Script Datei
SET WRITE_DELAY 0 MILLIS
setzten.
Dann funktioniert das.


----------

