DISCLAIMER: This is not a "please fix my broken app" question. I'm not looking for a solution or a workaround. In fact, I've already provided one myself. This question is about why the API was designed this way.
roomDB = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "my-db")
.addCallback(new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
roomDB.getDao().insert(someEntity);
}
})
.build();
This code leads straight into an Exception:
java.lang.IllegalStateException: getDatabase called recursively
Why? Because the onCreate
callback already provides a database instance in its parameter and the line roomDB.getDao().insert(someEntity);
is somehow trying to get another. The consequence of onCreate
providing a database instance is that the database cannot be accessed with the abstractions Room provides, but only directly. The documentation even warns about not to work with the SQLiteDatabase directly.
I have to say this again: The very first time, when I want to access my shiny new Room database, I'm forced to work with the low level SQLiteDatabase instead because of the design of the API.
My question is: Why? Is this a bug in the API design? Or are there legitimate use cases, where accessing the SQLiteDatabase directly is preferable?
If there was no SupportSQLiteDatabase instance in the parameters to onCreate
, I would expect this code to work fine:
roomDB = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "my-db")
.addCallback(new RoomDatabase.Callback() {
@Override
public void onCreate() {
roomDB.getDao().insert(someEntity);
}
})
.build();
EDIT: The database is ready, when the onCreate
callback is invoked:
db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "my-db")
.addCallback(new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
Log.d("DB", "onCreate called");
}
})
.build();
Log.d("DB", "database ready");
Because control flow already moved past the setup of the database, when the onCreate
callback is invoked:
D/DB: database ready
...
D/DB: onCreate called