I'm trying to get my app to backup & restore its DB file (e.g. mydatabase.db). Backup runs fine - it exports a single .db file. It doesn't export the -shm / -wal files because I run a 'pragma wal_checkpoint(full)' to flush any updates to the main file. Restore appears to run fine but afterwards when my app queries the newly copied data I get this error (but the app doesn't crash).
E/ROOM: Invalidation tracker is initialized twice :/.
E/SQLiteLog: (1) no such table: room_table_modification_log
E/ROOM: Cannot run invalidation tracker. Is the db closed?
android.database.sqlite.SQLiteException: no such table: room_table_modification_log
If I then try to update any of the data I get these 2 errors (and now the app does crash):
java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.
...
E/ROOM: Cannot run invalidation tracker. Is the db closed?
android.database.sqlite.SQLiteException: no such table: room_table_modification_log (code 1 SQLITE_ERROR):
If I close my app, and re-start it, everything runs fine and the new data can be queried/updated without error. I'm using Room 2.2.5 and see this error on different devices I have (Android 6 and 10).
My code below. I close the DB before doing the restore otherwise the app DB doesn't get updated.
private void dbImport() {
// DB Backup file to import (e.g. mydatabasebackup.db)
final Uri backupFile = viewModel.getDBImportFile();
String internalDBFile = context.getDatabasePath(APP_DATABASE_NAME).toString();
// Close app database
MyDatabase.destroyInstance();
restoreDatabase(backupFile, internalDBFile);
}
private void restoreDatabase(Uri backupFile, String internalDBFile) {
InputStream inputStream = context.getContentResolver().openInputStream(backupFile);
OutputStream outputStream = new FileOutputStream(internalDBFile);
// Copy backup -> DB
byte[] buffer = new byte[1024];
int read;
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
inputStream.close();
// Write the output file (this has now copied the file)
outputStream.flush();
outputStream.close();
}
And my Room Db class
public abstract class MyDatabase extends RoomDatabase {
private static MyDatabase DB_INSTANCE;
public static MyDatabase getDatabase(final Context context) {
if (DB_INSTANCE == null) {
synchronized (MyDatabase.class) {
if (DB_INSTANCE == null) {
DB_INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
MyDatabase.class, APP_DATABASE_NAME)
.addMigrations(new Migration_1_2(context, 1, 2))
.build();
}
}
}
return DB_INSTANCE;
}
public static void destroyInstance() {
if (DB_INSTANCE != null) {
if (DB_INSTANCE.isOpen()) {
DB_INSTANCE.close();
}
DB_INSTANCE = null;
}
}
-shm
and-wal
files prior to callingrestoreDatabase
? 2. Can you add Migration_1_2? – Stanzel