向现有房间数据库添加一列,同时使用房间版本 2.4.0-alpha01 中可用的当前自动迁移功能
Add a column to existing room database whilst using the current auto-migration feature available in room version 2.4.0-alpha01
我有一个包含数据的房间数据库,现在我想向其中添加另一列。
Room 版本 2.4.0-alpha01 及更高版本应该使自动迁移更容易,所以我这样使用它:
...
version = 2,
autoMigrations = {
@AutoMigration(from = 1, to = 2)
},
exportSchema = true
然后在我的模型 class 中,我添加了新的列名称并生成了它的 setter 和 getter,就像其他的一样。
room 文档说,如果 room 由于复杂的架构更改而无法执行迁移,则会抛出编译时错误。但是,就我而言,我收到有关预期模式和新模式(我添加了一列的模式)之间差异的运行时错误。
错误如下:
java.lang.RuntimeException: Exception while computing database live data.
at androidx.room.RoomTrackingLiveData.run(RoomTrackingLiveData.java:92)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.lang.IllegalStateException: Migration didn't properly handle: accounts(com.bisform.susu.models.Account).
Expected:
TableInfo{name='accounts', columns={accountSavings=Column{name='accountSavings', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountName=Column{name='accountName', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateTime=Column{name='accountCreateTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfDeposits=Column{name='numberOfDeposits', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, accountNumber=Column{name='accountNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfWithdrawals=Column{name='numberOfWithdrawals', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, accountPayoutDate=Column{name='accountPayoutDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, phoneOfNextOfKin=Column{name='phoneOfNextOfKin', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountImageURI=Column{name='accountImageURI', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountID=Column{name='accountID', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, lastUpdatedDate=Column{name='lastUpdatedDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, phoneNumber=Column{name='phoneNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountPayoutTime=Column{name='accountPayoutTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, lastUpdatedTime=Column{name='lastUpdatedTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, nameOfNextOfKin=Column{name='nameOfNextOfKin', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateDate=Column{name='accountCreateDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, isPaidOut=Column{name='isPaidOut', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
Found:
E/AndroidRuntime: TableInfo{name='accounts', columns={accountSavings=Column{name='accountSavings', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountName=Column{name='accountName', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateTime=Column{name='accountCreateTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfDeposits=Column{name='numberOfDeposits', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, accountNumber=Column{name='accountNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfWithdrawals=Column{name='numberOfWithdrawals', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, accountPayoutDate=Column{name='accountPayoutDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountImageURI=Column{name='accountImageURI', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountID=Column{name='accountID', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, lastUpdatedDate=Column{name='lastUpdatedDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, phoneNumber=Column{name='phoneNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountPayoutTime=Column{name='accountPayoutTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, lastUpdatedTime=Column{name='lastUpdatedTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateDate=Column{name='accountCreateDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, isPaidOut=Column{name='isPaidOut', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
at androidx.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:103)
...
请问我应该如何处理这个错误?如何使用当前存在的自动迁移功能获得正确迁移的空间?
Please what should I do to handle this error? How do I get room to migrate properly using the auto-migrate feature currently present?
我相信如果您以某种方式省略了自动迁移,您只会得到这个。我相信,使用您展示的代码,唯一的方法是包含手动迁移,因为这将覆盖自动迁移。
测试如下所示。
测试
此测试显示了从 V1 到 V2 覆盖 AutoMigration 的效果,以及未覆盖时迁移的工作方式。
测试基于 Accounts class 根据您预期的 (v2) 和找到的 (v1) 消息构建。
所以账户 class 是 :-
@Entity(tableName = "accounts")
class Accounts {
//String phoneOfNextOfKin; //<<<<< For V2 else commented out
//String nameOfNextOfKin; //<<<<< for V2 else commented out
String accountSavings;
String accountName;
String accountCreateTime;
Integer numberOfDeposits;
String accountNumber;
int numberOfWithdrawals;
String accountPayoutDate;
String accountImageURI;
@PrimaryKey
Long accountId;
String lastUpdatedDate;
String phoneNumber;
String accountPayoutTime;
String lastUpdatedTime;
String accountCreateDate;
boolean isPaidOut;
}
- 请注意带有注释的行//<<<<< ....,是已更改的行(针对 V1 注释掉并包含在 V2 中)
- 即为 V2
添加了 2 列 phoneOfNextOfKin 和 nameOfNextOfKin
@Dao class 在不同版本之间没有变化:-
@Dao
abstract class AccountsDao {
@Insert
abstract long insert(Accounts accounts);
@Query("SELECT * FROM accounts")
abstract List<Accounts> getAllFromAccounts();
}
一个@Database class :-
@Database(
entities = {Accounts.class},
version = TheDatabase.DBVERSION
/* following line, if no schema saved, needs to be commented out */
, autoMigrations = {@AutoMigration(from = 1, to = 2)}
)
abstract class TheDatabase extends RoomDatabase {
abstract AccountsDao getAccountsDao();
public static final int DBVERSION = 1; //<<<<< change accordingly
private static volatile TheDatabase instance = null;
static TheDatabase getInstance(Context context) {
if (instance == null) {
instance = Room.databaseBuilder(
context,
TheDatabase.class,
"accounts.db"
)
.allowMainThreadQueries() //run on main thread for brevity and convenience
.addMigrations(MIGRATION_1_2) //<<<<< if included then Migration didn't properly handle:
.build();
}
return instance;
}
/* Only needed for creating error shown in question */
/* doesn't hurt if no addMigrations or when creating V1 */
static final Migration MIGRATION_1_2 = new Migration(1,2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
}
};
}
最后是下面的 activity :-
public class MainActivity extends AppCompatActivity {
TheDatabase db;
AccountsDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = TheDatabase.getInstance(this);
dao = db.getAccountsDao();
Accounts a = new Accounts();
a.accountCreateDate = "2021-01-01";
a.accountCreateTime = "08:00:00";
a.accountImageURI = "imageURI";
a.accountName = "MyAccount";
a.accountNumber = "0000000000";
a.accountPayoutDate = "2021-05-05";
a.accountPayoutTime = "10:00:00";
a.accountSavings = "savings";
a.lastUpdatedDate = "2021-05-03";
a.lastUpdatedTime = "09:15:00";
a.numberOfDeposits = 10;
a.numberOfWithdrawals = 5;
a.isPaidOut = false;
//a.nameOfNextOfKin = "Mr Next of Kin"; //<<<<< For V2
//a.phoneOfNextOfKin = "1111111111"; //<<<<< For V2
dao.insert(a);
for(Accounts account: dao.getAllFromAccounts()) {
String msg = "Account is " + account.accountName + " ID is " + account.accountId;
if (TheDatabase.DBVERSION > 1) {
//msg = msg + " next of kin is " + account.nameOfNextOfKin; //<<<<< For V2
}
Log.d("ACCOUNTINFO", msg);
}
}
}
运行s 和结果:-
- 使用上述代码(不包含 V2 代码)且未安装应用程序。即创建 V1 数据库:-
App运行成功,Database Inspector显示:-
架构和单行一样符合预期。
- 运行 没有任何变化
- App运行成功,Database Inspector显示:-
3。对 V2 所做的更改特别是:-
在帐户名称和 phone 中包括近亲。
在 TheDatabase DBVERSION 中从 1 更改为 2 并且 .addMigrations 包含在内
在调用 activity 时,姓名和近亲值被分配值而不是被注释掉。连接 msg 变量以包括近亲。
应用程序崩溃
:-
Caused by: java.lang.IllegalStateException: Migration didn't properly handle: accounts(a.a.so69442030javaroomautomigrationsaddcolumns.Accounts).
Expected:
2021-10-05 14:31:50.669 30268-30268/a.a.so69442030javaroomautomigrationsaddcolumns E/AndroidRuntime: TableInfo{name='accounts', columns={accountSavings=Column{name='accountSavings', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountName=Column{name='accountName', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateTime=Column{name='accountCreateTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfDeposits=Column{name='numberOfDeposits', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountNumber=Column{name='accountNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfWithdrawals=Column{name='numberOfWithdrawals', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, phoneOfNextOfKin=Column{name='phoneOfNextOfKin', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountPayoutDate=Column{name='accountPayoutDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountImageURI=Column{name='accountImageURI', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountId=Column{name='accountId', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, lastUpdatedDate=Column{name='lastUpdatedDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, phoneNumber=Column{name='phoneNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountPayoutTime=Column{name='accountPayoutTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, nameOfNextOfKin=Column{name='nameOfNextOfKin', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, lastUpdatedTime=Column{name='lastUpdatedTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateDate=Column{name='accountCreateDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, isPaidOut=Column{name='isPaidOut', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
Found:
2021-10-05 14:31:50.670 30268-30268/a.a.so69442030javaroomautomigrationsaddcolumns E/AndroidRuntime: TableInfo{name='accounts', columns={accountSavings=Column{name='accountSavings', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountName=Column{name='accountName', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateTime=Column{name='accountCreateTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfDeposits=Column{name='numberOfDeposits', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountNumber=Column{name='accountNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfWithdrawals=Column{name='numberOfWithdrawals', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, accountPayoutDate=Column{name='accountPayoutDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountImageURI=Column{name='accountImageURI', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountId=Column{name='accountId', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, lastUpdatedDate=Column{name='lastUpdatedDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, phoneNumber=Column{name='phoneNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountPayoutTime=Column{name='accountPayoutTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, lastUpdatedTime=Column{name='lastUpdatedTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateDate=Column{name='accountCreateDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, isPaidOut=Column{name='isPaidOut', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
at androidx.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:103)
- 即复制遇到的失败
卸载应用程序并使用 V1 中的代码(从头开始演示整个过程)后重新运行步骤 1-2(重新运行 .addMigrations 注释掉或删除会解决这个问题)
已应用第 3 步的更改但另外数据库构建中的 .addMigrations 行已被注释掉。
- 应用程序没有崩溃。数据库检查器在新插入的行中显示修改后的模式和适当的数据(另外 2 个对于两个添加的列有空值):-
解决上述问题所需要做的就是清理项目并重新构建。我想旧模式不知何故仍在内存中,因此崩溃。
我有一个包含数据的房间数据库,现在我想向其中添加另一列。
Room 版本 2.4.0-alpha01 及更高版本应该使自动迁移更容易,所以我这样使用它:
...
version = 2,
autoMigrations = {
@AutoMigration(from = 1, to = 2)
},
exportSchema = true
然后在我的模型 class 中,我添加了新的列名称并生成了它的 setter 和 getter,就像其他的一样。
room 文档说,如果 room 由于复杂的架构更改而无法执行迁移,则会抛出编译时错误。但是,就我而言,我收到有关预期模式和新模式(我添加了一列的模式)之间差异的运行时错误。
错误如下:
java.lang.RuntimeException: Exception while computing database live data.
at androidx.room.RoomTrackingLiveData.run(RoomTrackingLiveData.java:92)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.lang.IllegalStateException: Migration didn't properly handle: accounts(com.bisform.susu.models.Account).
Expected:
TableInfo{name='accounts', columns={accountSavings=Column{name='accountSavings', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountName=Column{name='accountName', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateTime=Column{name='accountCreateTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfDeposits=Column{name='numberOfDeposits', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, accountNumber=Column{name='accountNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfWithdrawals=Column{name='numberOfWithdrawals', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, accountPayoutDate=Column{name='accountPayoutDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, phoneOfNextOfKin=Column{name='phoneOfNextOfKin', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountImageURI=Column{name='accountImageURI', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountID=Column{name='accountID', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, lastUpdatedDate=Column{name='lastUpdatedDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, phoneNumber=Column{name='phoneNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountPayoutTime=Column{name='accountPayoutTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, lastUpdatedTime=Column{name='lastUpdatedTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, nameOfNextOfKin=Column{name='nameOfNextOfKin', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateDate=Column{name='accountCreateDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, isPaidOut=Column{name='isPaidOut', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
Found:
E/AndroidRuntime: TableInfo{name='accounts', columns={accountSavings=Column{name='accountSavings', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountName=Column{name='accountName', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateTime=Column{name='accountCreateTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfDeposits=Column{name='numberOfDeposits', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, accountNumber=Column{name='accountNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfWithdrawals=Column{name='numberOfWithdrawals', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, accountPayoutDate=Column{name='accountPayoutDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountImageURI=Column{name='accountImageURI', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountID=Column{name='accountID', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, lastUpdatedDate=Column{name='lastUpdatedDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, phoneNumber=Column{name='phoneNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountPayoutTime=Column{name='accountPayoutTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, lastUpdatedTime=Column{name='lastUpdatedTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateDate=Column{name='accountCreateDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, isPaidOut=Column{name='isPaidOut', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
at androidx.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:103)
...
请问我应该如何处理这个错误?如何使用当前存在的自动迁移功能获得正确迁移的空间?
Please what should I do to handle this error? How do I get room to migrate properly using the auto-migrate feature currently present?
我相信如果您以某种方式省略了自动迁移,您只会得到这个。我相信,使用您展示的代码,唯一的方法是包含手动迁移,因为这将覆盖自动迁移。
测试如下所示。
测试
此测试显示了从 V1 到 V2 覆盖 AutoMigration 的效果,以及未覆盖时迁移的工作方式。
测试基于 Accounts class 根据您预期的 (v2) 和找到的 (v1) 消息构建。
所以账户 class 是 :-
@Entity(tableName = "accounts")
class Accounts {
//String phoneOfNextOfKin; //<<<<< For V2 else commented out
//String nameOfNextOfKin; //<<<<< for V2 else commented out
String accountSavings;
String accountName;
String accountCreateTime;
Integer numberOfDeposits;
String accountNumber;
int numberOfWithdrawals;
String accountPayoutDate;
String accountImageURI;
@PrimaryKey
Long accountId;
String lastUpdatedDate;
String phoneNumber;
String accountPayoutTime;
String lastUpdatedTime;
String accountCreateDate;
boolean isPaidOut;
}
- 请注意带有注释的行//<<<<< ....,是已更改的行(针对 V1 注释掉并包含在 V2 中)
- 即为 V2 添加了 2 列 phoneOfNextOfKin 和 nameOfNextOfKin
@Dao class 在不同版本之间没有变化:-
@Dao
abstract class AccountsDao {
@Insert
abstract long insert(Accounts accounts);
@Query("SELECT * FROM accounts")
abstract List<Accounts> getAllFromAccounts();
}
一个@Database class :-
@Database(
entities = {Accounts.class},
version = TheDatabase.DBVERSION
/* following line, if no schema saved, needs to be commented out */
, autoMigrations = {@AutoMigration(from = 1, to = 2)}
)
abstract class TheDatabase extends RoomDatabase {
abstract AccountsDao getAccountsDao();
public static final int DBVERSION = 1; //<<<<< change accordingly
private static volatile TheDatabase instance = null;
static TheDatabase getInstance(Context context) {
if (instance == null) {
instance = Room.databaseBuilder(
context,
TheDatabase.class,
"accounts.db"
)
.allowMainThreadQueries() //run on main thread for brevity and convenience
.addMigrations(MIGRATION_1_2) //<<<<< if included then Migration didn't properly handle:
.build();
}
return instance;
}
/* Only needed for creating error shown in question */
/* doesn't hurt if no addMigrations or when creating V1 */
static final Migration MIGRATION_1_2 = new Migration(1,2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
}
};
}
最后是下面的 activity :-
public class MainActivity extends AppCompatActivity {
TheDatabase db;
AccountsDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = TheDatabase.getInstance(this);
dao = db.getAccountsDao();
Accounts a = new Accounts();
a.accountCreateDate = "2021-01-01";
a.accountCreateTime = "08:00:00";
a.accountImageURI = "imageURI";
a.accountName = "MyAccount";
a.accountNumber = "0000000000";
a.accountPayoutDate = "2021-05-05";
a.accountPayoutTime = "10:00:00";
a.accountSavings = "savings";
a.lastUpdatedDate = "2021-05-03";
a.lastUpdatedTime = "09:15:00";
a.numberOfDeposits = 10;
a.numberOfWithdrawals = 5;
a.isPaidOut = false;
//a.nameOfNextOfKin = "Mr Next of Kin"; //<<<<< For V2
//a.phoneOfNextOfKin = "1111111111"; //<<<<< For V2
dao.insert(a);
for(Accounts account: dao.getAllFromAccounts()) {
String msg = "Account is " + account.accountName + " ID is " + account.accountId;
if (TheDatabase.DBVERSION > 1) {
//msg = msg + " next of kin is " + account.nameOfNextOfKin; //<<<<< For V2
}
Log.d("ACCOUNTINFO", msg);
}
}
}
运行s 和结果:-
- 使用上述代码(不包含 V2 代码)且未安装应用程序。即创建 V1 数据库:-
App运行成功,Database Inspector显示:-
架构和单行一样符合预期。
- 运行 没有任何变化
- App运行成功,Database Inspector显示:-
3。对 V2 所做的更改特别是:-
在帐户名称和 phone 中包括近亲。
在 TheDatabase DBVERSION 中从 1 更改为 2 并且 .addMigrations 包含在内
在调用 activity 时,姓名和近亲值被分配值而不是被注释掉。连接 msg 变量以包括近亲。
应用程序崩溃
:-
Caused by: java.lang.IllegalStateException: Migration didn't properly handle: accounts(a.a.so69442030javaroomautomigrationsaddcolumns.Accounts).
Expected:
2021-10-05 14:31:50.669 30268-30268/a.a.so69442030javaroomautomigrationsaddcolumns E/AndroidRuntime: TableInfo{name='accounts', columns={accountSavings=Column{name='accountSavings', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountName=Column{name='accountName', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateTime=Column{name='accountCreateTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfDeposits=Column{name='numberOfDeposits', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountNumber=Column{name='accountNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfWithdrawals=Column{name='numberOfWithdrawals', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, phoneOfNextOfKin=Column{name='phoneOfNextOfKin', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountPayoutDate=Column{name='accountPayoutDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountImageURI=Column{name='accountImageURI', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountId=Column{name='accountId', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, lastUpdatedDate=Column{name='lastUpdatedDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, phoneNumber=Column{name='phoneNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountPayoutTime=Column{name='accountPayoutTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, nameOfNextOfKin=Column{name='nameOfNextOfKin', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, lastUpdatedTime=Column{name='lastUpdatedTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateDate=Column{name='accountCreateDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, isPaidOut=Column{name='isPaidOut', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
Found:
2021-10-05 14:31:50.670 30268-30268/a.a.so69442030javaroomautomigrationsaddcolumns E/AndroidRuntime: TableInfo{name='accounts', columns={accountSavings=Column{name='accountSavings', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountName=Column{name='accountName', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateTime=Column{name='accountCreateTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfDeposits=Column{name='numberOfDeposits', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountNumber=Column{name='accountNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, numberOfWithdrawals=Column{name='numberOfWithdrawals', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, accountPayoutDate=Column{name='accountPayoutDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountImageURI=Column{name='accountImageURI', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountId=Column{name='accountId', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, lastUpdatedDate=Column{name='lastUpdatedDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, phoneNumber=Column{name='phoneNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountPayoutTime=Column{name='accountPayoutTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, lastUpdatedTime=Column{name='lastUpdatedTime', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, accountCreateDate=Column{name='accountCreateDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, isPaidOut=Column{name='isPaidOut', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
at androidx.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:103)
- 即复制遇到的失败
卸载应用程序并使用 V1 中的代码(从头开始演示整个过程)后重新运行步骤 1-2(重新运行 .addMigrations 注释掉或删除会解决这个问题)
已应用第 3 步的更改但另外数据库构建中的 .addMigrations 行已被注释掉。
- 应用程序没有崩溃。数据库检查器在新插入的行中显示修改后的模式和适当的数据(另外 2 个对于两个添加的列有空值):-
解决上述问题所需要做的就是清理项目并重新构建。我想旧模式不知何故仍在内存中,因此崩溃。