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.

Room attempt to re-open an already-closed object: SQLiteDatabase

See original GitHub issue

@florina-muntenescu Sorry, please look again. Db is not upgraded when I call Database Singleton again. Thanks for your support.

There was version 1 Database, I changed to version 2 and started application.

@Database(entities = [Feed::class, NewsWidget::class, NewsWidgetFeed::class], version = 2)
abstract class Database : RoomDatabase() {

    abstract fun feedDao(): FeedDao
    abstract fun newsWidgetDao(): NewsWidgetDao
    abstract fun newsWidgetFeedDao(): NewsWidgetFeedDao

    companion object {

        @Volatile private var INSTANCE: com.icebergteam.cryptocoinassistant.data.room.Database? = null

        fun getInstance(context: Context): com.icebergteam.cryptocoinassistant.data.room.Database =
                INSTANCE ?: synchronized(this) {
                    INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
                }

        private val IO_EXECUTOR = Executors.newSingleThreadExecutor()

        /**
         * Utility method to run blocks on a dedicated background thread, used for io/database work.
         */
        fun ioThread(f: () -> Unit) {
            IO_EXECUTOR.execute(f)
        }

        private fun buildDatabase(context: Context) =
                Room.databaseBuilder(context.applicationContext,
                        com.icebergteam.cryptocoinassistant.data.room.Database::class.java, "settings.db")
                        .addMigrations(MIGRATION_1_2)
                        .fallbackToDestructiveMigration()
                        .addCallback(object : RoomDatabase.Callback() {
                            override fun onOpen(db: SupportSQLiteDatabase) {
                                LogManager.LogEA(db.version)
                                super.onOpen(db)

                            }

                            override fun onCreate(db: SupportSQLiteDatabase) {
                                super.onCreate(db)
                                ioThread {
                                    getInstance(context).feedDao().insert(*INIT_FEED_TABLE)
                                }
                            }
                        })
                        .build()

        val MIGRATION_1_2: Migration = object: Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL("ALTER TABLE NewsWidget ADD COLUMN interval_anim INTEGER DEFAULT 6000")
            }
        }

        val INIT_FEED_TABLE = arrayOf(
                Feed("https://censor.net.ua/includes/resonance_ru.xml"),
                Feed("https://geektimes.ru/rss/interesting/"),
                Feed("http://k.img.com.ua/rss/ru/companies.xml"))
    }
}

Using Database NewsRepositoryImpl is repository, using Singleton Database for select and insert transactions So RxJava call Database.getInstance(context) twice, when first emit data and into flatMap (please look screenshot)

Database.getInstance(context)
Database.getInstance(context)

or

Database.getInstance(this).feedDao().getAllFeed()
.flatMap({ url -> Database.getInstance(this).feedDao().getItem(url)})
01-09 20:03:20.801 9784-9812/? E/AndroidRuntime: FATAL EXCEPTION: pool-3-thread-1
                                                 Process: com.icebergteam.cryptocoinassistant, PID: 9784
                                                 java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.icebergteam.cryptocoinassistant/databases/settings.db
                                                     at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
                                                     at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1659)
                                                     at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1605)
                                                     at android.arch.persistence.db.framework.FrameworkSQLiteDatabase.execSQL(FrameworkSQLiteDatabase.java:240)
                                                     at com.icebergteam.cryptocoinassistant.data.room.Database$Companion$MIGRATION_1_2$1.migrate(Database.kt:60)
                                                     at android.arch.persistence.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:73)
                                                     at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onUpgrade(FrameworkSQLiteOpenHelper.java:118)
                                                     at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:256)
                                                     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
                                                     at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:93)
                                                     at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:54)
                                                     at android.arch.persistence.room.RoomDatabase.inTransaction(RoomDatabase.java:305)
                                                     at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:281)
                                                     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                                                     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                                                     at java.lang.Thread.run(Thread.java:818)

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:9
  • Comments:12 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
wenqin-231commented, Mar 13, 2018

Maybe you should not use addMigrations and fallbackToDestructiveMigration both

1reaction
drayan85commented, Dec 20, 2018

Thanks, @KevinPosim. I have some issues with my legacy codes to Migrate AndroidX to use Room 2.0.0; I have Managed to find the issue.

In my SQLiteHelper (older version) one column for Long Primitive Type

created_at=Column{name='created_at', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}

In the Room Entity Class, I have define the primitive type as follows private Long created_at which created as follows ( Not Null):

created_at=Column{name='created_at', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0}

For Example If the RoomDatabase Extended Class Name AppDatabase.Java after the build, There will be a class Call AppDatabase_Impl.java

By debugging the AppDatabase_Impl.Java generated class we can find which Table Migration is failed.

        final HashMap<String, TableInfo.Column> _columnsTblTrackerEvent = new HashMap<String, TableInfo.Column>(6);
        _columnsTblTrackerEvent.put("_id", new TableInfo.Column("_id", "INTEGER", true, 1));
        _columnsTblTrackerEvent.put("created_at", new TableInfo.Column("created_at", "INTEGER", false, 0));
        _columnsTblTrackerEvent.put("activity_type", new TableInfo.Column("activity_type", "TEXT", false, 0));
        _columnsTblTrackerEvent.put("country", new TableInfo.Column("country", "TEXT", false, 0));
        _columnsTblTrackerEvent.put("params_object", new TableInfo.Column("params_object", "TEXT", false, 0));
        final HashSet<TableInfo.ForeignKey> _foreignKeysTblTrackerEvent = new HashSet<TableInfo.ForeignKey>(0);
        final HashSet<TableInfo.Index> _indicesTblTrackerEvent = new HashSet<TableInfo.Index>(1);
        _indicesTblTrackerEvent.add(new TableInfo.Index("index_tbl_tracker_event__id", true, Arrays.asList("_id")));
        final TableInfo _infoTblTrackerEvent = new TableInfo("tbl_tracker_event", _columnsTblTrackerEvent, _foreignKeysTblTrackerEvent, _indicesTblTrackerEvent);
        final TableInfo _existingTblTrackerEvent = TableInfo.read(_db, "tbl_tracker_event");

       /** **Below If Condition is failed and Throws IllegalStateException** */
        if (! _infoTblTrackerEvent.equals(_existingTblTrackerEvent)) {
          throw new IllegalStateException("Migration didn't properly handle tbl_tracker_event(com.room.sample.TrackerEventLog).\n"
                  + " Expected:\n" + _infoTblTrackerEvent + "\n"
                  + " Found:\n" + _existingTblTrackerEvent);
        }

But when run the app, it crash and throwing IllegalState Exception but the error message

java.lang.IllegalStateException: attempt to re-open an already-closed object

Instead of ::

"Migration didn't properly handle tbl_tracker_event(com.room.sample.TrackerEventLog).\n" + " Expected:\n" + _infoTblTrackerEvent + "\n" + " Found:\n" + _existingTblTrackerEvent

Read more comments on GitHub >

github_iconTop Results From Across the Web

Attempt to reopen an already-closed object sqlitedatabase
Attempt to reopen an already -closed object sqlitedatabase · 1. Simply open it by using the line something called myDb.open(). Then do your...
Read more >
java.lang.IllegalStateException: attempt to re-open an already ...
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: (database path) This issue has happened for ...
Read more >
attempt to re-open an already-closed object: SQLiteDatabase ...
Allows Room to destructively recreate database tables if Migrations that would migrate old database schemas to the latest schema version are not found....
Read more >
Android: Getting 'IllegalStateException: attempt to re-open an ...
Android: Getting 'IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: path/securidDB'.
Read more >
attempt to reopen an already-closed object sqlitedatabase room
attempt to reopen an already -closed object sqlitedatabase room ... In Room New Version 1.0.0-alpha9 Room adds support for the NOT NULL constraint....
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 Reddit Thread

No results found

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