Search code examples
androidandroid-room

Room migration not executed on empty database


I have Room database within my application with a migration step that read the app private folder and populate the DB accordingly. The migration works well when I run it if the database is not empty.

If the database is completely empty, then I see no logs of my migration step being executed.

I peeked at Room code in RoomOpenHelper, could not find anything.

Does anyone have a pointer on this ?


Solution

  • A Migration, is invoked when a change has been detected in the schema AND the version number of the database is increased.

    • If only the former then an exception would occur indicating that the latter is required (unless you have utilised one of the .fallbackToDestructiveMigration methods of the Room databaseBuilder)

    • When a project is compiled a hash of the schema is generated. Such as e8377db1dd2fc73ae411eecff1a98372.

      • If the database does not exist, this hash is stored in the room_master_table as part of the createAllTables method. If the database exists then the compiled hash is compared against the stored hash in the onValidateSchema method.
    • The compiled version number is similarly compared against one stored in the database (in the header as the SQLite USER VERSION). See https://www.sqlite.org/fileformat.html#user_version_number

    • After compilation of the project, there will be a class in the java(generated) (visible via the Android View) that is the same name as the @Database annotated class but suffixed with _Impl the above mentioned methods appear in this class.

    When a database does not exist no Migration is performed as neither the schema hash or the version exist, instead the database is created and the schema hash and version stored.

    If you want to populate the new database then you typically either provide a pre-packaged database and utilise the createFromAsset (or createFromFile) or you utilise the Callback's onCreate to override the default action of doing nothing and undertake the required actions within the method. Noting that you would utilise the .addCallback method of the Room databaseBuilder