14

I try use room library from google architecture. I write few codes based on the BasicSample from google, but database not created (for my code). Logcat does not contains errors and exceptions. Please help me find my mistake:

//App.java
//...
public class App extends Application {
    private AppExecutors mAppExecutors;
    private static final String TAG = "App";

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate: enter");
        mAppExecutors = new AppExecutors();
        getDatabase();
    }

    public AppDatabase getDatabase() {
        return AppDatabase.getInstance(this, mAppExecutors);
    }
}

My AppDatabase class looks:

//AppDatabase.java
//...
@Database(entities = {Camera.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    private static final String DATABASE_NAME = "mydatabase";
    private static AppDatabase sInstance;
    private AppExecutors mExecutors;
    public abstract CameraDao cameraModel();

    public static AppDatabase getInstance(final Context context, final AppExecutors executors) {
        if (sInstance == null) {
            synchronized (AppDatabase.class) {
                if (sInstance == null) {
                    sInstance = buildDatabase(context.getApplicationContext(), executors);
                }
            }
        }
        return sInstance;
    }
    private static final String TAG = "AppDatabase";
    private static AppDatabase buildDatabase(final Context context, final AppExecutors executors) {
        Log.i(TAG, "buildDatabase: enter");
        AppDatabase database = Room.databaseBuilder(context, AppDatabase.class, DATABASE_NAME)
                .addCallback(new Callback() {

                    @Override
                    public void onCreate(@NonNull SupportSQLiteDatabase db) {
                        Log.i(TAG, "onCreate: ");
                        super.onCreate(db);

                        executors.diskIO().execute(() -> getInstance(context, executors).initDb());
                    }
                })
                .build();
        database.mExecutors = executors;
        Log.i(TAG, "buildDatabase: exit");
        return database;
    }

    private void initDb() {
        cameraModel().insert(new Camera(1, "Canon", "EOS 5d Mark III", 1024, 768, 24, 22, 0.0, true));
    }
}

Dao interface:

//CameraDao.java
@Dao
public interface CameraDao {
    @Insert
    void insert(Camera camera);
}

And Entity class:

// Camera.java
@Entity
public class Camera {
    @PrimaryKey(autoGenerate = true)
    public long id;
    public String list_name;
    public String camera_name;
    public int max_resolution_width;
    public int max_resolution_height;
    public int max_sensor_width;
    public int max_sensor_height;
    public double coc;
    public boolean is_auto_coc;

    public Camera(long id, String list_name, String camera_name, int max_resolution_width, int max_resolution_height, int max_sensor_width, int max_sensor_height, double coc, boolean is_auto_coc) {
        this.id = id;
        this.list_name = list_name;
        this.camera_name = camera_name;
        this.max_resolution_width = max_resolution_width;
        this.max_resolution_height = max_resolution_height;
        this.max_sensor_width = max_sensor_width;
        this.max_sensor_height = max_sensor_height;
        this.coc = coc;
        this.is_auto_coc = is_auto_coc;
    }

    @Ignore
    public Camera(String list_name, String camera_name, int max_resolution_width, int max_resolution_height, int max_sensor_width, int max_sensor_height, double coc, boolean is_auto_coc) {
        this.list_name = list_name;
        this.camera_name = camera_name;
        this.max_resolution_width = max_resolution_width;
        this.max_resolution_height = max_resolution_height;
        this.max_sensor_width = max_sensor_width;
        this.max_sensor_height = max_sensor_height;
        this.coc = coc;
        this.is_auto_coc = is_auto_coc;
    }
}

So, with this code database could not created. Callback for create db not called. Btw, if I have autoincrement field is it possible insert custom value (for special conditions).

My logcat for this code:

12-04 00:54:47.536 9150-9150/ru.neverdark.photonotes I/App: onCreate: enter

12-04 00:54:47.537 9150-9150/ru.neverdark.photonotes I/AppDatabase: buildDatabase: enter

12-04 00:54:47.541 9150-9150/ru.neverdark.photonotes I/AppDatabase: buildDatabase: exit

Community
  • 1
  • 1
Artem
  • 691
  • 2
  • 5
  • 22
  • 2
    "database not created" -- where is the code that uses any of this? `AppDatabase.getInstance()` is not going to create the database, any more than creating an instance of a `SQLiteOpenHelper` will create the database. It is only when you first try reading or writing that the database will be created. – CommonsWare Dec 03 '17 at 15:11
  • @CommonsWare great! Problem solved – Artem Dec 03 '17 at 15:17

1 Answers1

51

Under the covers, by default, Room uses SQLiteOpenHelper, much as you might use it directly.

SQLiteOpenHelper does not create the database when you create the SQLiteOpenHelper instance. It will do so once you call getReadableDatabase() or getWriteableDatabase().

From a Room standpoint, that means until you perform some concrete operation, such as invoking a @Dao method that hits the database, your database will not be created.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 1
    My usecase is that I want to access the db immediately on the home page. But the prepopulating is take a bit longer. Thus, when I query the db, I get no results as the tables are still in the process of filling up. What should I do in this case? Shall I make a dummy call to the db on the splash screen? Or is there a way to avoid this kind of lazy loading? – Priya Sindkar May 06 '21 at 11:32
  • @PriyaSindkar: "Shall I make a dummy call to the db on the splash screen?" -- if there is data that your app is likely to use, make a call for that and cache it. Otherwise, make some cheap call (e.g., get the count of rows in some table), I guess. "Or is there a way to avoid this kind of lazy loading?" -- that would not really help you. Suppose that it takes 5 seconds to populate your database. That 5 seconds is not because of lazy-loading; it is because of the work involved. So, it will take 5 seconds whether lazy-loaded or not. – CommonsWare May 06 '21 at 12:10
  • 1
    Ok. Thanks a lot. Your answers helped a lot. – Priya Sindkar May 06 '21 at 12:15
  • 1
    Another off-track question, if I may- Do wrongly used coroutine scopes affect the populating speed? – Priya Sindkar May 06 '21 at 12:16
  • 1
    @PriyaSindkar: "Do wrongly used coroutine scopes affect the populating speed? " -- I do not know what Room does if it is in the middle of pre-populating the database and the coroutine scope that governs the overall piece of work gets canceled. Ideally, the pre-population work continues to completion, but I have not tested this scenario. – CommonsWare May 06 '21 at 12:34