Damon Getsman
Newbie
This is the third time that I've attempted to write a migration in order to update my database layout with Room (in java). The first two times I ended up just giving up, because no matter what I tried I couldn't get anything to work. I was in a place, previously, where I could just allow a destructive migration, instead, but at this point in development I really need a working migration; I do not want to have to rely on destructive migrations with the amount of data that I currently have in the database. I mean it's not distributed yet, so there aren't other users that'd have to deal with the fallout, but I know I need to learn how do to it The Right Way(tm) anyway, so I'm persisting in working on this migration until it happens, or until I've learned that it's just impossible with Room, which hopefully is not the case. I doubt it would've been recommended to me on #android-dev in the first place if such were the case, though I've found a lot of people that are urging me away from it now due to issues like this that seem to be a bit more common than I would like.
So my problem is fairly simple to describe, at least. I've got an existing database with a couple of tables that are working just fine, but I need to add a new table for some features that are now up on the implementation list. Oh, and I have updated to the latest version of Room, which is (if I'm not mistaken) 1.1.1 currently.
The new table (UsualSuspects.java) that I'm trying to add follows (er well the class that implements it, anyway):
AppDatabase code, including the new migration, follows:
When I'm attempting to run the application with the following migration, I'm receiving the following error from Room (forgive the lack of a full stack trace, I'll run it again and include that at the end here, though I do believe this is the applicable bit from it:
As you can see, the only discrepancy (as far as I can tell) between what is expected and what is found is that the columns are arranged differently; however, I can't for the life of me find where that is echoed in the code that I've written. I'm really not sure where on earth to go with this next.
In case it's necessary, the following snippets (in order) are for UsualSuspectDbase and UsualSuspectDao:
I would be very grateful for any help that anyone might be able to offer in how I can go about fixing this issue, or some good resources that would spell it out to me a little bit better than what I've found already. I've looked at a ton of google hits already on StackExchange and the like and I'm not able to find anything that's helped so far. Also grateful for any other pointers in the right direction, though honestly I really don't want to try to rewrite this application with something other than Room ORM unless it's absolutely the only way to do it. I'm still kind of an Android environment newbie, and I don't want to have to try to learn a whole different ORM (provided some exist) unless there's no other route to go.
I'm very grateful for any assistance, as I've said, and thank you in advance for anything that you might have to offer. Please let me know if more information is necessary in order to track down this bug appropriately and I'll get it up as soon as I can. TIA
So my problem is fairly simple to describe, at least. I've got an existing database with a couple of tables that are working just fine, but I need to add a new table for some features that are now up on the implementation list. Oh, and I have updated to the latest version of Room, which is (if I'm not mistaken) 1.1.1 currently.
The new table (UsualSuspects.java) that I'm trying to add follows (er well the class that implements it, anyway):
Code:
package com.example.sprite.half_lifetimer;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
@Entity(tableName="UsualSuspect")
public class UsualSuspect {
@PrimaryKey(autoGenerate = true)
private int id;
@ColumnInfo(name="name")
private String name;
@ColumnInfo(name="sid")
private int sid;
@ColumnInfo(name="dosage")
private float dosage;
@ColumnInfo(name="notes")
private String notes;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public float getDosage() {
return dosage;
}
public void setDosage(float dosage) {
this.dosage = dosage;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public UsualSuspect() { }
}
AppDatabase code, including the new migration, follows:
Code:
package com.example.sprite.half_lifetimer;
import android.arch.persistence.db.SupportSQLiteDatabase;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.arch.persistence.room.TypeConverters;
import android.arch.persistence.room.migration.Migration;
import android.content.Context;
@Database(entities = {Substance.class, Usage.class, UsualSuspect.class}, version = 4)
@TypeConverters({Converters.class})
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
public abstract SubstanceDao getSubstanceDao();
public abstract UsageDao getUsageDao();
public abstract UsualSuspectDao getUsualSuspectDao();
public static AppDatabase getDatabase(Context ctxt) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(ctxt.getApplicationContext(), AppDatabase.class,
GlobalMisc.DbName)
.allowMainThreadQueries()
//.fallbackToDestructiveMigration()
//.addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4)
.build();
}
return INSTANCE;
}
static final Migration MIGRATION_3_4 = new Migration(3, 4) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE IF NOT EXISTS `UsualSuspect` (`id` INTEGER, `sid` " +
"INTEGER NOT NULL, `dosage` REAL NOT NULL, `notes` VARCHAR NOT NULL, " +
"PRIMARY KEY (`id`))");
}
};
public static void destroyInstance() { INSTANCE = null; }
}
When I'm attempting to run the application with the following migration, I'm receiving the following error from Room (forgive the lack of a full stack trace, I'll run it again and include that at the end here, though I do believe this is the applicable bit from it:
Code:
Expected:
TableInfo{name='UsualSuspect', columns={name=Column{name='name', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, dosage=Column{name='dosage', type='REAL', affinity='4', notNull=true, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1}, notes=Column{name='notes', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, sid=Column{name='sid', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}}, foreignKeys=[], indices=[]}
Found:
TableInfo{name='UsualSuspect', columns={dosage=Column{name='dosage', type='REAL', affinity='4', notNull=true, primaryKeyPosition=0}, notes=Column{name='notes', type='VARCHAR', affinity='2', notNull=true, primaryKeyPosition=0}, name=Column{name='name', type='VARCHAR', affinity='2', notNull=true, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1}, sid=Column{name='sid', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}}, foreignKeys=[], indices=[]}
As you can see, the only discrepancy (as far as I can tell) between what is expected and what is found is that the columns are arranged differently; however, I can't for the life of me find where that is echoed in the code that I've written. I'm really not sure where on earth to go with this next.
In case it's necessary, the following snippets (in order) are for UsualSuspectDbase and UsualSuspectDao:
Code:
package com.example.sprite.half_lifetimer;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.RoomDatabase;
@Database(entities = {UsualSuspect.class}, version = 1)
public abstract class UsualSuspectDbase extends RoomDatabase {
public abstract UsualSuspectDao usualSuspectDao();
}
Code:
package com.example.sprite.half_lifetimer;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Query;
import java.util.List;
@Dao
public interface UsualSuspectDao {
@Query("SELECT * FROM UsualSuspect")
List<UsualSuspect> getAll();
}
I would be very grateful for any help that anyone might be able to offer in how I can go about fixing this issue, or some good resources that would spell it out to me a little bit better than what I've found already. I've looked at a ton of google hits already on StackExchange and the like and I'm not able to find anything that's helped so far. Also grateful for any other pointers in the right direction, though honestly I really don't want to try to rewrite this application with something other than Room ORM unless it's absolutely the only way to do it. I'm still kind of an Android environment newbie, and I don't want to have to try to learn a whole different ORM (provided some exist) unless there's no other route to go.
I'm very grateful for any assistance, as I've said, and thank you in advance for anything that you might have to offer. Please let me know if more information is necessary in order to track down this bug appropriately and I'll get it up as soon as I can. TIA