Cliff
Cliff

Reputation: 713

Room Persistance Error

I have an app that uses Room persistence at production mode. Its seems when i try to update a table i have the following error on some devices: My connection with database is open all time, only on destroy i release the db.

This is my Service that runs every 12 hours

This is Service: https://gist.github.com/anonymous/8fac7650b34aa19229d5f6b91d2454d4 DataRepo : https://gist.github.com/anonymous/70c524c1e8eb5e7ed893131a9c685b5b AppDatabase https://gist.github.com/anonymous/ccb20853054fa5d453592fd2653a4dc4

the error:

java.lang.IllegalStateException: 
     at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked 
    (SQLiteDatabase.java:2199)
     at android.database.sqlite.SQLiteDatabase.createSession 
    (SQLiteDatabase.java:379)
    at android.database.sqlite.SQLiteDatabase$1.initialValue 
    (SQLiteDatabase.java:92)
    at android.database.sqlite.SQLiteDatabase$1.initialValue 
    (SQLiteDatabase.java:89)
    at java.lang.ThreadLocal$Values.getAfterMiss (ThreadLocal.java:430)
    at java.lang.ThreadLocal.get (ThreadLocal.java:65)
    at android.database.sqlite.SQLiteDatabase.getThreadSession 
    (SQLiteDatabase.java:373)
    at android.database.sqlite.SQLiteProgram.getSession (SQLiteProgram.java:101)
    at android.database.sqlite.SQLiteStatement.executeUpdateDelete 
    (SQLiteStatement.java:64)
    at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete (FrameworkSQLiteStatement.java:75)
     at android.arch.persistence.room.EntityDeletionOrUpdateAdapter.handle (EntityDeletionOrUpdateAdapter.java:69)
      at mbc.analytics.sdk.room.dao.TimeDao_Impl.updateTimeModel (TimeDao_Impl.java:122)
      at mbc.analytics.sdk.room.database.DatabaseRepository.createTimeEntity (DatabaseRepository.java:211)
      at mbc.analytics.sdk.room.database.DatabaseRepository.createAppEntity (DatabaseRepository.java:56)
      at mbc.analytics.sdk.services.LollipopService.getStats (LollipopService.java:202)
      at mbc.analytics.sdk.services.LollipopService.access$900 (LollipopService.java:39)
    at mbc.analytics.sdk.services.LollipopService$2.run (LollipopService.java:153)
      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)

Upvotes: 1

Views: 1232

Answers (1)

Xavier Rubio Jansana
Xavier Rubio Jansana

Reputation: 6583

DatabaseRepository is wrapping a call to Room.databaseBuilder(). As this is implemented using a singleton, you're closing the database in the call to databaseRepository.databaseClose();, but not opening again. The creation of a new DatabaseRepository in your code doesn't help, as AppDatabase.getAppDatabase(ctx); will return the same closed database.

So, possible solutions will be:

  • Remove the call to databaseRepository.databaseClose();, as the service is running inside the same Application as the rest of your Activities, and the database is (and should be) shared. This is the preferred solution in my opinion.
  • An alternative will be that DatabaseRepository#databaseClose() also destroys the database object by calling AppDatabase.destroyInstance();. To me, this is can pose other issues, like concurrency issues, retained references to the old database object (e.g. in an activity), etc.

Code for the second, not recommended solution:

public void databaseClose() {
    if (db.isOpen()) {
        db.close();
        AppDatabase.destroyInstance();
    }
}

Upvotes: 2

Related Questions