Room persistent library reset version to 1 - android

Is there any ways to reset room library version to 1. I tried uninstall the app on my phone. It is not working.

There's actually a faster way, if you're okay with loosing your data. But I guess above option is no better in that sense.
When you build your database you have to set .fallbackToDestructiveMigration() like in the following example.
database = Room
.databaseBuilder(getApplicationContext(), ActionsDatabase.class, "database.db")
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build();
This way every time you change you database version the database gets rebuild. You can also change your version number back and forth, so going from 1 to 2 and back to 1, if you like.

Downgrading versions using Room only works if you completly remove the app.
You can either do that via adb (adb uninstall your.app.package) which removes your databases aswell, or you delete the data/cache in your app-overview using your device.

I found the simple solution to reset the Room DataBase to Version 1.
In my application i will have a Test.db sqlite file which i have Created intially using SQL ite browser.
When i need to Reset the Room Database to Version 1.
I will Create a New DataBase(Test.db )file in the SQL ite Browser making all required changes needed. And paste the Database file in the Asset folder. Keeping the Version to 1.
This worked for me.

Thanks #wschopohl
My problem have fixed, follow the your way. I had could return version Room Database to 1.
So, the easy & simple way to return version to 1 is you need to add the line method .fallbackToDestructiveMigration() when building the Database.
And then, you can up version to "n" and back to 1, example 1 to 2 and back to 1.
Like this:
database = Room
.databaseBuilder(getApplicationContext(), ActionsDatabase.class, "database.db")
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build();

Related

How do I supress a Room database schema change error?

I'm just toying around with my schema and I can't get my app to load at all since I changed the schema/Entity class.
I have deleted the app on my testing devic, cleared the caches on AndroidStudio, and rebooted my machine but the error persists. All I did was change the default values of one of my Entity data classes for my Room database.
How do I force AndroidStudio to forget about the old table schema/Entity class without incrementing the version number and providing a migration path?
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.
Android Studio doesn't save the database schema information, your app does. So you can clear the app data on your test device and will fix the problem without incrementing your version number.
However without clearing the app data, you can use RoomDatabase.Builder.fallbackToDestructiveMigration() along with incrementing the version number to avoid implementing migration logic if you're happy to lose the contents of the previous database.
You can try setting android:allowBackup to false in the manifest file.

java.lang.IllegalStateException when assessing ROOM database first time in app

I have a couple applications which were using com.readystatesoftware.sqliteasset.SQLiteAssetHelper to read in read-only databases (never updated during an application session). For some reason, I decided to refactor them to use ROOM.
All works correctly in my emulators and on the one Android phone that I have, but once released the apps are crashing frequently (maybe every time) for my users. This is occurring at the first time in the app where my code is calling a database query.
Here is the stack trace
java.lang.IllegalStateException:
at androidx.room.RoomOpenHelper.onUpgrade (RoomOpenHelper.java:138)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onUpgrade (FrameworkSQLiteOpenHelper.java:9)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked (SQLiteOpenHelper.java:400)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase (SQLiteOpenHelper.java:298)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase (FrameworkSQLiteOpenHelper.java:4)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase (FrameworkSQLiteOpenHelper.java:2)
at androidx.room.SQLiteCopyOpenHelper.getWritableDatabase (SQLiteCopyOpenHelper.java:13)
at androidx.room.RoomDatabase.inTransaction (RoomDatabase.java:2)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction (RoomDatabase.java)
at com.XXX.YYY.model.bah.dao.BahDao_Impl.getInfoFromDatabase (BahDao_Impl.java:13)
at com.XXX.YYY.model.MyClass.getInfoFromDatabase (MyClass.java:20)
at com.XXX.YYY.controller.MyFragment$UpdateBahInfoTask.run (MyFragment.java:17)
at java.lang.Thread.run (Thread.java:764)
These are the first versions of these applications which are using ROOM, so I am not sure why the onUpgrade method is being called or if that is an indication where the issue lies. I am kind of at a loss of where to go with this. My use of these databases is very simple (e.g. just performing queries based on user actions). I cannot replicate this on the emulators or actual device even when upgrading the old app to the new version using adb.
I did start the database version at the same number used by the Sqlite version of the apps, so that is the only thing that maybe could be causing this.
#Database(entities = {Table1.class, Table2.class, Table3.class}, exportSchema = true, version = 14)
public abstract class BahDatabase extends RoomDatabase {
public abstract BahDao bahDao();
}
I am thinking that I will:
increment the database versions
add a call to .addMigrations(MIGRATION_14_15) when I build the database
//Used for creating singleton
private MyClass(Context context) {
mBahDatabase = Room.databaseBuilder(context, BahDatabase.class, DATABASE_NAME_ROOM)
.createFromAsset(DATABASE_ASSET_FULL_PATH)
.addMigrations(MIGRATION_14_15)
.build();
}
And just put a stub for that migration class that will do nothing (as nothing in the database is changing)
static final Migration MIGRATION_14_15 = new Migration(14, 15) {
#Override
public void migrate(SupportSQLiteDatabase database) {
// Since we didn't alter the table, there's nothing else to do here.
Log.d(TAG, "MIGRATION_14_15 Called");
}
};
UPDATE: The above three steps had no effect as the new version of the app is still crashing with this same error.
UPDATE2: Replaced call to addMigrations(MIGRATION_14_15) with call to fallbackToDestructiveMigration(). As my database created from createFromAsset() is never changed by the app, I could care less if Android balks during some ill conceived migration. The JavaDoc states the below which is fine with my design as the database in my assets folder is always what the app should be using (in regards to tables and data):
If the database was create from an asset or a file then Room will try to use the same file to re-create the database, otherwise this will delete all of the data in the database tables managed by Room.
Will see what happens
Any thoughts?
Thanks in advance.
IllegalStateException occurs when your application invokes a method at inappropriate times. Looking at your stack trace. the issues maybe arising from these areas.
....
at com.XXX.YYY.model.bah.dao.BahDao_Impl.getInfoFromDatabase (BahDao_Impl.java:13)
at com.XXX.YYY.model.MyClass.getInfoFromDatabase (MyClass.java:20)
at com.XXX.YYY.controller.MyFragment$UpdateBahInfoTask.run (MyFragment.java:17)
You should check those methods in model and controller files in your code.
So I made that change to add a call to fallbackToDestructiveMigration() when building the database, and that appears to prevent the crashes. So the relevant part of my singleton which builds the database is below:
mBahDatabase = Room.databaseBuilder(context, BahDatabase.class, DATABASE_NAME_ROOM)
.createFromAsset(DATABASE_ASSET_FULL_PATH)
.fallbackToDestructiveMigration()
.build();
Now, I have no idea why this works or what the underlying problem was. To restate:
This was the first version of my application which used a Room database. Previously I used com.readystatesoftware.sqliteasset.SQLiteAssetHelper to copy the database from the asset folder and use the copy as a read-only database in my app.
Therefore, Room should not be doing any method calling related to migrations.
I suspect that Room was having some kind of issue with the old database on a user's phone which was copied over by com.readystatesoftware.sqliteasset.SQLiteAssetHelper in a previous version of my app.
Based on the above, I suspect that this is some odd Android bug, but not many app devs are likely in the scenario that I am in regards to the refactoring to Room.
Luckily, I could care less about what Room did during its migration processing as the database provided in my apk is the one I want to use (also not modified by the app) and any database updates are always provided in a subsequent apk.
No matter what scenarios I created in regards to what was on the emulator/phone before I installed the new app, I could never get the app to crash (like my users were seeing) when using an emulator or an old Android phone.
You cannot run a new Migration(14, 15) when the #Database annotation still says version = 14. It shouldn't throw an IllegalStateException when the #Database annotation would be version = 15. Generally speaking, when the current version is 14, it makes no sense to migrate to 15 (as 14 currently is the latest version in existence). Also see Understanding migrations with Room.

Android Room requires migration after data insertion by another app

I'm developing an Android app with an embedded SQLite database run with Android Room. I'm moving the app from desktop Java to Android and I need to bring data into the Android database from the old database used with the desktop app. I ran into a problem with Room when I tried using the altered database with my Android app.
I tried taking the database file created by Room and move the data from the old database into this one with a short Java app I coded for this purpose. I simply emptied the relevant tables, read data from the old database and inserted it into the new database.
When I tried moving the database file back to my Android devide and using it with the Android app I got this exception:
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.
If I change the version of the database in my Room database code, Room would then require a piece of code for the migration even though the structure of the database has not been changed:
java.lang.IllegalStateException: A migration from 1 to 2 was required but not found. Please provide the necessary Migration path via RoomDatabase.Builder.addMigration(Migration ...) or allow for destructive migrations via one of the RoomDatabase.Builder.fallbackToDestructiveMigration* methods.
I tried clearing the app data cache and clearing all of its data and even uninstalling the app, then reinstalling it with the modified database file. Didn't make the problem go away. I also tried everything here Room cannot verify the data integrity including setting android:allowBackup="false" in my Manifest, and adding fallbackToDestructiveMigration to my database. After trying fallbackToDestructiveMigration, all of my new database's data was gone. But then I put the altered database file back in again and it worked. To be honest, I'm not entirely sure what step made it work. I think it was increasing the version number, running it with fallbackToDestructiveMigration and then moving the new database file back in again when fallbackToDestructiveMigration had wiped data from the database...
My question is how can Room know the database has been modified when there hadn't been any change to its structure that would make it incompatible with the Entities of my app? And how can know even though I've cleared the app's data from the device? And are there any steps I should take the next time that are not mentioned above? I quess I could just include migration code that does nothing. But that seems kind of silly, I'd like the version number to stay at 1 since the app is in development at the moment.
Add an empty Migration.
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
// empty migration.
}
}
if (sInstance == null) {
if (!checkDataBase())
copyDataBase(context)
synchronized(AppDatabase::class) {
sInstance = Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, DATABASE_NAME)
.addMigrations(MIGRATION_1_2)
.build()
}
}
return sInstance!!
You can check out this Migration Guide from Florina Muntenescu to learn more about Migrations

When new table is added in room db from version 1 to version 2

I am using Room Persistance library which android has released as a alternative for SQLite Database.
I am currently having Android app on playstore with SQLite Database and While migrating app from SQLite to Room, I am facing several errors.
First
If I create new table do I need to write migration script i.e; I need to write migration query in Room everytime I upgrade the room version?
Second
I have the DB version on playstore with version of 20 and when I upgrade it to 21. Do I need to write migration scripts from 1 to 20 and 20 to 21 or only from 20 to 21.
Because I don't know what app db version does user have (production app), it can be 10,12, 15. How will the migration scripts be?
Thank you.
Every time you add a table (or make any schema change) you need to either a) add a migration or b) call .fallbackToDestructiveMigration() ONLY IF YOU DON'T CARE ABOUT PERSISTING THE DATA. Check out https://medium.com/google-developers/understanding-migrations-with-room-f01e04b07929 for more.
You'll need to write a migration script for every database your user could be on to upgrade them to 21 (again, unless you don't care about persisting data, in which case you can use .fallbackToDestructiveMigration()). This above link should also address this question.
Hope this helps!

Upgrade database with Sqlite.net Pcl for Xamarin android

i have the problem that when i release new version of my application, if i add a new column to one of my db tables, the database doesn't update. Any one know how to create a script of upgrade versione in case there are new columns or new tables??
Thanks
You have to remember that CreateTable it's already doing the columns update for you, because internally it calls a method called MigrateTable.
However you could have to handle more advanced modification to your database, like adding triggers or something similar.
In that case i suggest you to perform modifications manually.
In Xamarin Forms i've ended up with this:
https://gist.github.com/matpag/b2545cc22c8e22449cd7eaf6b4910396
Could not be the best strategy ever but seems to work for me.
Summarizing :
You have to save the database version in an internal flag of the SQlite database called user_version accessible with PRAGMA keyword.
Every time you get the database connection, you have to perform a check and see if the current database version is the same as the app last database version.
If not you need to perform a database update and set the new current version.
It's not a matter of a script, as there isn't such a thing. You can release a version with a "patch" that will run once, extracting all your records to a temporary form -> deleting the table -> creating it again (will assure it's created with the new columns and so on) -> reinserting the records again. After a while, when you know that all your users (or whenever you set the limit) have moved to the newer version you can just eliminate the "patch" from your code.
Hope it helps.
The automatic migration feature is still not working in sqlite.net-pcl, but it looks like it does work in the other sqlite package: sqlite-net-pcl, which is actually the Xamarin recommend sqlite package.

Categories

Resources