Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Failed to create a table on in-memory sqlite database without any error message

Tags:

java

sqlite

jdbc

I am trying to create a table on in-memory sqlite database. I have a method called createTable to create a table which initializes a connection to the database with getConnection method.

createTable:

private void createTable() {
    try {
        final Connection connection = getConnection();
        final Statement statement = connection.createStatement();
        statement.execute(
            "CREATE TABLE videos (id INTEGER PRIMARY KEY, title VARCHAR(255), description TEXT, path TEXT, category VARCHAR(255), published INTEGER DEFAULT 0, created TIMESTAMP DEFAULT CURRENT_TIMESTAMP);");
        statement.close();
        connection.close();
    } catch (final SQLException e) {
        LOGGER.warn("Failed to create table.", e);
    }
}

getConnection

private static Connection getConnection() {
    try {
        Class.forName("org.sqlite.JDBC");
        return DriverManager.getConnection("jdbc:sqlite:");
    } catch (final Exception e) {
        LOGGER.warn("Failed to get connection.", e);
        throw new RuntimeException(e);
    }
}

To test the database I wrote a simple insert method:

public void insert() {
    try {
        final Connection connection = getConnection();
        final Statement statement = connection.createStatement();
        statement.executeUpdate(
            "INSERT INTO videos (title, path, category) VALUES ('test title', 'test path', 'test category');");
        statement.close();
        connection.close();
    } catch (final SQLException e) {
        LOGGER.warn("Failed to insert.", e);
    }
}

When I do

this.createTable();
this.insert();

I got the following error:

2017-09-17 22:38:02 WARN  Database:128 - Failed to insert.
org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (no such table: videos)
    at org.sqlite.core.DB.newSQLException(DB.java:909)
    at org.sqlite.core.DB.newSQLException(DB.java:921)
    at org.sqlite.core.DB.throwex(DB.java:886)
    at org.sqlite.core.NativeDB._exec_utf8(Native Method)
    at org.sqlite.core.NativeDB._exec(NativeDB.java:87)
    at org.sqlite.jdbc3.JDBC3Statement.executeUpdate(JDBC3Statement.java:116)...

For connections I am using org.xerial:sqlite-jdbc's v3.20.0.

Any ideas why table is not getting created? I am not seeing any exception or anything. SQLFiddle for the example above seems to be fine.

like image 377
mert Avatar asked Sep 18 '17 05:09

mert


People also ask

How can I force a SQLite database to exist purely in memory?

The most common way to force an SQLite database to exist purely in memory is to open the database using the special filename ":memory:". In other words, instead of passing the name of a real disk file into one of the sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2()functions, pass in the string ":memory:". For example:

What happens to the SQLite in-memory database when connection is closed?

And when the connection gets closed, the Sqlite In-memory database will be removed. So I modified your code a little bit like this.

How do I create a SQLite database file?

On Linux, MacOS, or WSL, open the terminal and touch a new database file to create it: This creates a 0-byte database file which is totally valid for SQLite! Try opening it (see below). There are a couple of ways to do this on Windows - using the file explorer, or using the command prompt.

How do I create a temporary database in SQLite 3?

rc = sqlite3_open("", &db); ATTACH DATABASE '' AS aux2; A different temporary file is created each time so that, just as with the special ":memory:" string, two database connections to temporary databases each have their own private database.


1 Answers

If I read the documentation correctly, the database only exists within its database connection by default:

Instead, a new database is created purely in memory. The database ceases to exist as soon as the database connection is closed. Every :memory: database is distinct from every other. So, opening two database connections each with the filename ":memory:" will create two independent in-memory databases.

The easiest fix would be to not open a second connection, but keep using the connection that you used to create the table for the other database queries as well.

If you want to open multiple connections, you can set the ?cache=shared parameter on the database url.

like image 153
Thilo Avatar answered Oct 11 '22 21:10

Thilo