I am upgrading an app from targeting sdk 25 to targeting sdk 29, all the tables in my room database have a @PrimaryKey annotation but were not annotated with @NonNull. Now that I am targeting sdk 29, room is requiring the @NonNull annotation, unfortunately that causes my app to crash on startup unless I do a fresh install.
Error it causes without fresh install:
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:318)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:
I figured that was because my database had to be migrated because it works on a fresh install.
So far I have found some helpful stack overflow answers such as this one.
But that would require me to rewrite every table in my database and making sure I bring all the indices over as well. I do not want to have to do this as I am sure I will miss something and it will create multiple bugs.
Is there a simpler way to do a room migration where I just add the @NonNull annotation to all my primary keys?
Alternatively I have seen mention of grabbing the schema from the SQLite tables that would encapsulate all the indices into a query, but I do not know how to get that schema in my migration.
Example class after I have added NonNull tag:
@Entity(tableName = "FavoriteTrip"
, indices = { @Index("tripPlanId") }
, foreignKeys = @ForeignKey(entity = TripPlan.class, parentColumns = "id", childColumns = "tripPlanId"))
public class FavoriteTrip {
@PrimaryKey @NonNull
private String id = UUID.randomUUID().toString();