When I upgrade my Database from Version 1 to Version 2 and insert new data then all old data stored in Version 1 of database were deleted and I can see only newly inserted data in database.
Any idea how to persist data while upgrading database with Room Library?
I found solution from the same link. And when the migration class is not provided then Room Library deletes whole Database with data on onUpgrade() and create Database again.
It is compulsory to provide Migration class if you want to persist data on onUpgrade()
Related
Should I increment the value of the Room database version if I change the content of the database when its migration strategy is set to "fallback to destructive migration"?
Following changes made to database:
Some columns are removed.
Content of some rows is updated in the database file that is stored in assets.
Yes. You should update the version of the database even with fallback to destructive migration strategy. Room uniquely identifies every database version with an "identity hash string", which is kept in a configuration table.
Keeping the database version unchanged will cause the app to crash with an IllegalStateException. Internally Room checks the identity of the database comparing the identity hash of the current version vs the the one stored in the table called "room_master_table".
You can learn more about this in the below article which also explains in detail how to handle version change and testing.
Reference: https://medium.com/androiddevelopers/understanding-migrations-with-room-f01e04b07929
UPDATE: It is interesting that the app crashed in some users, but for some users including me, it didn't crash. So it's better to update the version of the database even though its migration strategy is fallback to destructive.
From my experience, it seems we don't have to increment the value of Room database version when its migration strategy is set to "fallback to destructive migration".
I changed the content of the database and removed some columns from the database file.
Then I installed the previous version of the app (unchanged database). Then I used the application and made sure a database instance is created.
Then I installed the new version of the app (changed database). And it didn't crash and everything worked fine. Changes applied to the database.
I want to update my app at play store with bug fixes. APP already uses Room DB. Do i need to migrate the DB. There is no change in the DB. There are only UI changes. Does new version effect the people DB, who are already using it. Can someone provide the details about this.
Thanks in advance.
There is no change in the DB.
The database remains and you do not need to change the version of the database (as per the #Database( .... version=?)).
You only need to change (increase) the database version if the schema has changed.
If you increase the version number and do not have a migration (migration class to call) to cover that version, then an IllegalStateException will occur unless you have .fallbackToDestructiveMigration() which WILL delete and recreate the database (effectively empty the database with the ne schema).
You can also use fallbackToDestructiveMigrationFrom()
It is the version number that determines if a database migration is required. However, if a change is made and if any of the entities mismatch the database when the .build method is run then an exception will result.
If you change an Entity (the schema) and do not increase the version number you will get an IllegalStateException with the message starting with Room cannot verify the data integrity. This is because the hash stored in the room_master_table has changed.
If you changed the database schema outside of room then you'd get an exception indicating that the expected schema (the database according to the Entities) does not match the schema found (the database according to the actual database).
In your situation I'd suggest not changing the version number.
You may wish to have a look at:-
Migrating Room Databases
#Database
fallbackToDestructiveMigration
fallbackToDestructiveMigrationFrom
Imagine I deliver a prepopulated database with my application version 1.
The prepopulated database includes a table "my_items" with the column item:
item
------
apple
For application version 2 I deliver an updated prepopulated database, so table "my_items" includes
item
------
apple
milk
How would one make sure that the new prepopulated data is transfered to the database of the app in a non-destructive way? (user is allowed to insert new items to "my_items" by himself and I need to keep his input). I read the Room migrations documentation, but it seems like the prepopulated data is only read on a destructive migration, which is not what I want, as the items entered by the user himself shall remain available.
Room's built in migration processing does not support the merging of existing data into a new prepopulated database.
An approach that should work is to give the prepackaged database file for each app version a unique name, e.g. my_items1.db, my_items2.db, etc. In app version 2, create the main database from prepackaged database file my_items2.db. Then open the database for the previous version as a separate Room database instance, query it to find the items added by the user, and insert those into the new main database with appropriate default values for new fields. This merge processing could be triggered by the onCreate() callback for the main database. The merge processing should be done in a transaction. If it completes successfully, you can close and delete the database for the previous version. In the event of failure, you'll need to notify the user and implement some sort of mitigation processing.
Our app has DB version 14 and uses the android sqllite helpers. Now we are moving to use the room db and migrating all the DB stuff to room. we have defined all the migrations from 1_2, 2_3 .. to 13_14 and give all these int the build
.databaseBuilder(
app,
Database::class.java,
"my.db"
).addMigrations(arrayOf(
MIGRATION_1_2,
MIGRATION_2_3,
.....
MIGRATION_10_11,
MIGRATION_11_12,
MIGRATION_12_13,
MIGRATION_13_14
))
.build()
Is this right way of doing. If i have the non room version of the app installed with DB version 14 and i try to update it to room version of the app with same db version 14, I am getting the error :
java.lang.IllegalStateException: Room cannot verify the data
integrity. Looks like you've changed schema but forgot to update the
version number. You can simply fix this by increasing the version
number.
You only need to add a migration from your existing SQLite database to a Room-managed database. This should be an empty "do nothing" migration. This is required so that Room plays nicely with your existing database.
I developed an Android-App where I saved data in a SQLite database using the SQLiteOpenHelper.
I am wondering if I could update my app by using ActiveAndroid, but in a way that the user data previously stored in the database will be preserved.
Is that possible?
You would have to perform a data migration during runtime after the user upgrades to the newest version of the app. The process could be broken down into the following steps, I have also assigned database version values to each step.
The user has all of their data stored in a SQLite database and has not upgraded their app yet. [DB = SQlite v1]
On upgrade, when the user is upgrading to the next version of the
app read all data from the old SQLite database and store it into the
ActiveAndroid database. [DB = SQLite v1 and ActiveAndroid v1]
Once all of the data has been migrated to the new ActiveAndroid database then delete all tables of the SQLite database so that you don't use extra storage space that you do not need. [DB = SQLite v2 and ActiveAndroid v1]
In the next release you can then assume that user has had their data fully migrated and at this point it is finally safe to remove all code that was previously referencing the SQLite database. [DB = ActiveAndroid v2]