Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to deal with indices info during ROOM migration

CODE:

@Entity(tableName = "UserRepo", indices = @Index(value = "id", unique = true))
public class GitHubRepo {
@PrimaryKey(autoGenerate = true)
public int _id;
public int id;
public String name;
public String description;
@Embedded
public RepoOwner owner;

public GitHubRepo(int id, String name, String description, RepoOwner owner) {
    this.id = id;
    this.name = name;
    this.description = description;
    this.owner = owner;
}

public class RepoOwner {
@ColumnInfo(name = "user_id")
public int id;
public String login;

public RepoOwner(int id, String login) {
    this.id = id;
    this.login = login;
}

Explain: I hava a ROOM database which contains a simple table UserRepo, this table contains three columns _id, id, name and use the "id" as the index in order to have a faster query. For now, I want to use the @Embedded annotation to add the owner info in this table. The Migration code is follow:

public static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE UserRepo ADD COLUMN user_id INTEGER");
        database.execSQL("ALTER TABLE UserRepo ADD COLUMN login TEXT");
    }
};

During the migration, I got an error of:

Expected: TableInfo

{name='UserRepo', columns={name=Column{name='name', type='TEXT', notNull=false, primaryKeyPosition=0}, description=Column{name='description', type='TEXT', notNull=false, primaryKeyPosition=0}, _id=Column{name='_id', type='INTEGER', notNull=true, primaryKeyPosition=1}, id=Column{name='id', type='INTEGER', notNull=true, primaryKeyPosition=0}, login=Column{name='login', type='TEXT', notNull=false, primaryKeyPosition=0}, user_id=Column{name='user_id', type='INTEGER', notNull=false, primaryKeyPosition=0}}, foreignKeys=[], **indices=[Index{name='index_UserRepo_id', unique=true, columns=[id]}]**}

Found: TableInfo

{name='UserRepo', columns={name=Column{name='name', type='TEXT', notNull=false, primaryKeyPosition=0}, description=Column{name='description', type='TEXT', notNull=false, primaryKeyPosition=0}, _id=Column{name='_id', type='INTEGER', notNull=true, primaryKeyPosition=1}, id=Column{name='id', type='INTEGER', notNull=true, primaryKeyPosition=0}, login=Column{name='login', type='TEXT', notNull=false, primaryKeyPosition=0}, user_id=Column{name='user_id', type='INTEGER', notNull=false, primaryKeyPosition=0}}, foreignKeys=[], **indices=[]**}

Seems I lost the indices info in my Migration implement, How can I fix this?

ANOTHER INFO I can fix this issue by remove the indices info from the GitHubRepo entity, But I don't want to do this, as I don't want to lose the advantage of indices.

like image 798
Jun Du Avatar asked Feb 22 '18 09:02

Jun Du


People also ask

What are the best practices for migrating room databases?

Migrating Room databases 1 Test migrations. Migrations are often complex, and an incorrectly-defined migration could cause your app to crash. ... 2 Gracefully handle missing migration paths. ... 3 Handle column default value when upgrading to Room 2.2.0. ...

Why does room ask me to implement an automigrationspec?

If Room detects ambiguous schema changes and it is unable to generate a migration plan without more input, it throws a compile-time error and asks you to implement an AutoMigrationSpec . Most commonly, this occurs when a migration involves one of the following: Deleting or renaming a table. Deleting or renaming a column.

When do I need a migration in room?

Any query apart for the migration should never happen in this layer of the implementation, for that, you can use D ao. You need a migration if there was any kind of database you want to conserve for your users, this is handled with Room, Rooms offers a migration wrapper like the next one:

How to create a migration object in room?

At runtime, Room runs each Migration class's migrate () method, using the correct order to migrate the database to a later version. Now we have created the migration object MIGRATION_1_2, we need to add it in the database configuration using database builder.


1 Answers

Finally, I fixed this issue by set an index for this table in Migrate.So the code is:

 public static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE UserRepo ADD COLUMN user_id INTEGER");
        database.execSQL("ALTER TABLE UserRepo ADD COLUMN login TEXT");
        database.execSQL("CREATE UNIQUE INDEX index_UserRepo_id ON UserRepo (id)");
    }
};

The third SQL line is the key.

like image 86
Jun Du Avatar answered Sep 28 '22 03:09

Jun Du