9

I am trying to use Room for my new app. But whenever I restart my app, I am unable to retrieve the old data. It looks like my app is creating a new instance of the database every time, but I am not sure why. Here are my classes based on MVP pattern.

Edit: I just checked again and I can see that the auto-generated Id for the Entity (MyModel) doesn't get reset to 1 but when I retrieve data I only get collection inserted in that session.

Dao

@Dao
public interface MyDao {

      @Insert(onConflict = OnConflictStrategy.REPLACE)
      List<Long> insertModels(List<MyModel> models);

      @Query("SELECT * FROM MyModel")
      List<MyModel> getModels();
}

Database

@Database(entities = {MyModel.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase {
    public abstract MyDao myDao();
}

DatabaseModule

@Module
public class DatabaseModule {

    @Provides
    @Singleton
    MyDatabase provideMyDatabase(Application context) {
        return Room.databaseBuilder(context.getApplicationContext(), MyDatabase.class, "MyDB").build();
    }

    @Provides
    @Singleton
    MyDao provideMyDao(MyDatabase myDatabase) {
        return myDatabase.myDao();
    }
}

Data Source

@Singleton
public class MyDataSource {

    MyDao mMyDao;

    @Inject
    public MyDataSource(@NonNull MyDao myDao) {
        mMyDao = myDao;
    }
}

Repository

@Singleton
public class MyRepository {

    private final MyDataSource mMyDataSource;

    @Inject
    MyRepository(@Local MyDataSource myDataSource) {
        mMyDataSource = myDataSource;
    }
}

ApplicationComponent

@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, ApplicationModule.class, DatabaseModule.class})
public interface ApplicationComponent extends AndroidInjector<MyApp> {

    @Component.Builder
    interface Builder {

        @BindsInstance
        Builder application(Application application);

        ApplicationComponent build();
    }
}

App

public class MyApp extends DaggerApplication {

    private ApplicationComponent mApplicationComponent;

    @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        mApplicationComponent = DaggerApplicationComponent.builder().application(this).build();
        return mApplicationComponent;
    }
}
fR0DDY
  • 795
  • 1
  • 8
  • 20
  • Are you sure that you're not somehow triggering the migration mechanism? That's the one thing that stands out to me in the Room docs: Caution: If you don't provide the necessary migrations, Room rebuilds the database instead, which means you'll lose all of your data in the database. (https://developer.android.com/training/data-storage/room/migrating-db-versions.html) – Eric O'Connell Nov 30 '17 at 19:26
  • 1
    No, it's version 1. Moreover, I am not re-installing the app, just restarting it. – fR0DDY Dec 01 '17 at 06:24
  • are you sure the values are getting inserted into db successfully ? You can try writing the test case as well which ensures that data is inserted and retrieved successfully . – Gautam Dec 01 '17 at 10:50
  • 1
    Yes, I am able to retrieve them using another query but only for the same session. Once I restart all previous data is gone. – fR0DDY Dec 01 '17 at 11:10
  • i would suggest you to pull out the db of the app and check after restarting the app the data is present in the db or not . That way you make sure somewhere through the code, its getting deleted by some query – Gautam Dec 04 '17 at 07:09
  • I have this problem too, user device is Nokia 5.1+ with more than 6GB free space – Shahriyar Aghajani Feb 07 '21 at 08:12

2 Answers2

3

i just saw the google example and how they did it, and i realized that you need to fix:

@Module public class DatabaseModule {

@Provides
@Singleton
MyDatabase provideMyDatabase(Application context) {
    return Room.databaseBuilder(context.getApplicationContext(), MyDatabase.class, "MyDB").build();
}

@Provides
@Singleton
MyDao provideMyDao(MyDatabase myDatabase) {
    return myDatabase.myDao();
}

}

to check if database already exist, with this code:

  /**
 * Check whether the database already exists and expose it via {@link #getDatabaseCreated()}
 */
private void updateDatabaseCreated(final Context context) {
    if (context.getDatabasePath(DATABASE_NAME).exists()) {
        setDatabaseCreated();
    }
}

private void setDatabaseCreated(){
    mIsDatabaseCreated.postValue(true);
}


public LiveData<Boolean> getDatabaseCreated() {
    return mIsDatabaseCreated;
}

anyway here is a link to github google sample about this: https://github.com/googlesamples/android-architecture-components/blob/master/BasicSample/app/src/main/java/com/example/android/persistence/db/AppDatabase.java

0

Ok. I also faced the same problem, My mistake was I was using the same db name in the builder for two room db. so it deletes the data on restart

Room.databaseBuilder(AppClass.instance, MatchedDB::class.java, "duplicate-db")

this duplicate-db name is used in other Room db within your android app

Jalees Mukarram
  • 106
  • 1
  • 4