question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

In-memory Sqlite DB disappears between transactions

See original GitHub issue

I have an in-memory sqlite db. The following code yields an error. Here’s the code:

import org.jetbrains.exposed.dao.EntityID
import org.jetbrains.exposed.dao.UUIDEntity
import org.jetbrains.exposed.dao.UUIDEntityClass
import org.jetbrains.exposed.dao.UUIDTable
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.jetbrains.exposed.sql.transactions.transaction
import photo.backup.kt.data.HashTable
import java.sql.Connection
import java.util.*

object MyTable: UUIDTable() {
    val name = varchar("name", 50)
}

class Name(id: EntityID<UUID>): UUIDEntity(id) {
    companion object: UUIDEntityClass<Name>(MyTable)

    var name by MyTable.name
}

fun main() {
    val db = Database.connect("jdbc:sqlite:file:test?mode=memory&cache=shared", "org.sqlite.JDBC")
    TransactionManager.manager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE
    transaction(db) {
        addLogger(StdOutSqlLogger)
        SchemaUtils.create(MyTable)
    }
    println(UUID.randomUUID())
    val id = transaction(db) {
        MyTable.insert {
            it[name] = "Foo"
        } get MyTable.id
    }
    println(id)
}

main()

Here’s the error:

Exception in thread "main" org.jetbrains.exposed.exceptions.ExposedSQLException: org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (no such table: My)
SQL: [INSERT INTO My (id, "name") VALUES (?, ?)]
	at org.jetbrains.exposed.sql.statements.Statement.executeIn$exposed_core(Statement.kt:50)
	at org.jetbrains.exposed.sql.Transaction.exec(Transaction.kt:122)
	at org.jetbrains.exposed.sql.Transaction.exec(Transaction.kt:108)
	at org.jetbrains.exposed.sql.statements.Statement.execute(Statement.kt:29)
	at org.jetbrains.exposed.sql.QueriesKt.insert(Queries.kt:45)
	at org.jetbrains.kotlin.idea.scratch.generated.ScratchFileRunnerGenerated$ScratchFileRunnerGenerated$main$id$1.invoke(tmp.kt:34)
	at org.jetbrains.kotlin.idea.scratch.generated.ScratchFileRunnerGenerated$ScratchFileRunnerGenerated$main$id$1.invoke(tmp.kt:16)
	at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt$inTopLevelTransaction$1.invoke(ThreadLocalTransactionManager.kt:156)
	at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt$inTopLevelTransaction$2.invoke(ThreadLocalTransactionManager.kt:197)
	at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.keepAndRestoreTransactionRefAfterRun(ThreadLocalTransactionManager.kt:205)
	at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.inTopLevelTransaction(ThreadLocalTransactionManager.kt:196)
	at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt$transaction$1.invoke(ThreadLocalTransactionManager.kt:134)
	at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.keepAndRestoreTransactionRefAfterRun(ThreadLocalTransactionManager.kt:205)
	at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction(ThreadLocalTransactionManager.kt:106)
	at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction(ThreadLocalTransactionManager.kt:104)
	at org.jetbrains.kotlin.idea.scratch.generated.ScratchFileRunnerGenerated$ScratchFileRunnerGenerated.main(tmp.kt:33)
	at org.jetbrains.kotlin.idea.scratch.generated.ScratchFileRunnerGenerated$ScratchFileRunnerGenerated.generated_get_instance_res0(tmp.kt:40)
	at org.jetbrains.kotlin.idea.scratch.generated.ScratchFileRunnerGenerated.main(tmp.kt:52)
Caused by: org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (no such table: My)
	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.prepare_utf8(Native Method)
	at org.sqlite.core.NativeDB.prepare(NativeDB.java:127)
	at org.sqlite.core.DB.prepare(DB.java:227)
	at org.sqlite.core.CorePreparedStatement.<init>(CorePreparedStatement.java:41)

chaging Database.connect("jdbc:sqlite:file:test?mode=memory&cache=shared", "org.sqlite.JDBC") to Database.connect("jdbc:sqlite:/path/to/data.db", "org.sqlite.JDBC")

then the DB is created and the insertion happens correctly

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:2
  • Comments:18 (3 by maintainers)

github_iconTop GitHub Comments

9reactions
kylegoetzcommented, Jan 2, 2020

Connection pooling with Hikari works. It might be useful to put a note about this in an example for Sqlite in-memory DBs since the docs don’t make it clear that a Sqlite in-memory DB will be destroyed between transactions. Here is sample code for using Hikari connection pooling with a Sqlite in-memory DB:

val cfg: HikariConfig = HikariConfig().apply {
    jdbcUrl = "dbc:sqlite::memory:"
    maximumPoolSize = 6
}
val dataSource = HikariDataSource(cfg)
val database = Database.connect(dataSource)

Now the in-memory DB will not be destroyed between transactions.

7reactions
trathschlagcommented, Oct 1, 2021

I used the following workaround:

val sqlitePath = "jdbc:sqlite:file:test?mode=memory&cache=shared"
val keepAliveConnection = DriverManager.getConnection(sqlitePath)
val db = Database.connect(sqlitePath)

As long as you don’t close() the keepAliveConnection, the Database will persist in memory. Not pretty, but works.

Read more comments on GitHub >

github_iconTop Results From Across the Web

In-memory SQLite and database disappearing - Stack Overflow
The database ceases to exist as soon as the database connection is closed. " However, this can be worked around with multiple connections...
Read more >
Does in memory db behave the same as a normal db - SQLite
I am testing a db application. The best would be to create the database for every test. I timed the creation of a...
Read more >
How To Corrupt An SQLite Database File
Failing that, it is safe to make a copy of an SQLite database file as long as there are no transactions in progress...
Read more >
File Locking And Concurrency In SQLite Version 3
Obtain an EXCLUSIVE lock on the database file and make sure all memory changes have been written to the database file using the...
Read more >
Atomic Commit In SQLite
We begin with an overview of the steps SQLite takes in order to perform an atomic commit of a transaction against a single...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found