Room Persistence Library:迁移过程中的奇怪错误

Posted

技术标签:

【中文标题】Room Persistence Library:迁移过程中的奇怪错误【英文标题】:Room Persistence Library: Weird Error during migration 【发布时间】:2018-04-05 09:08:36 【问题描述】:

这个错误让我摸不着头脑。到目前为止我找不到任何答案。我有旧数据库,我正在迁移到 Persistence Room 库。但是,每当我进行迁移时,都会出现以下错误,

java.lang.IllegalStateException: Migration didn't properly handle. 

我使用的代码如下:

@Entity(tableName = ROUTE_TABLE)
public class RouteData 

    static final String ROUTE_TABLE = "name";

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    private int id;
    @ColumnInfo(name = "col1")
    private String col1;
    //Other columns with exactly same as 'col1' just different names
    //Getters and Setters

对于迁移,

Room.databaseBuilder(context.getApplicationContext(), MyData.class, DATABASE_NAME)
            .addMigrations(MIGRATION_LATEST)
            .fallbackToDestructiveMigration() 
            .build();

private static final Migration MIGRATION_LATEST = new Migration(9, 10) 
    @Override
    public void migrate(SupportSQLiteDatabase db) 
        //Log.i("Tag" , "Migration Started");
        //Migration logic
        //Log.i("Tag" , "Migration Ended");
    
;

当我运行程序时。我在我的 LogCat 中收到“迁移结束”日志,但是当我再次尝试访问数据库时,它给了我以下错误。

 Caused by: java.lang.IllegalStateException: Migration didn't properly handle xxx.
                                                                              Expected:
                                                                             TableInfoname='name', columns=col1=Columnname='col1', type='TEXT', notNull=false, primaryKeyPosition=0, ...., foreignKeys=[]
                                                                              Found:
                                                                             TableInfoname='name', columns=col1=Columnname='col1', type='INTEGER', notNull=false, primaryKeyPosition=0, ...., foreignKeys=[]

我不知道这个“INTEGER”从哪里来。我尝试卸载、使缓存无效和任何其他密切相关的解决方案。知道发生了什么吗?如果您新安装应用程序,它工作得非常好。错误仅在迁移后出现。根据我的日志猫,所有迁移步骤似乎都已完成,但仍显示迁移未正确处理。

【问题讨论】:

您可以在迁移之前添加您的模型吗? @JoséCarlos,哪个型号? 你的 RouteData 类 @SnehPandya 感谢您对帮助我表现出兴趣。但是最近发现了真正的原因,请检查答案:) @JoséCarlos 感谢您对帮助我的兴趣。但是最近发现了真正的原因,请检查答案:) 【参考方案1】:

感谢大家的帮助,但经过几天令人沮丧的调试后,我终于找到了答案。在我的应用清单中,自动备份已打开,

android:allowBackup="true"

因此,在尝试各种数据库时,谷歌实际上是在备份我所有新创建的数据库及其结构,并在我重新安装应用程序时自动恢复它们。因此,我收到了这个有线错误。一旦我切换自动备份android:allowBackup="false" 并重新安装应用程序,我可以正确测试迁移。

我对所有未来遇到此类问题的开发人员的建议,SWITCH OFF在开发时自动备份。测试迁移后,您可以将其打开。

【讨论】:

或者在重新安装旧版本之前,清除您的应用数据。 Settings > Apps > your app > Storage > Clear Data @StuStirling,这对我来说不起作用。谷歌在安装新版本时总是将我的数据库设置为以前的状态。因此,这在迁移时会出现问题。【参考方案2】:

迁移脚本中的主要问题如下:

Caused by: java.lang.IllegalStateException: Migration didn't properly handle xxx.
                                                                              Expected:
                                                                             TableInfoname='name', columns=col1=Columnname='col1', type='TEXT', notNull=false, primaryKeyPosition=0, ...., foreignKeys=[]
                                                                              Found:
                                                                             TableInfoname='name', columns=col1=Columnname='col1', type='INTEGER', notNull=false, primaryKeyPosition=0, ...., foreignKeys=[]

在这里,在您的实体类中:

@ColumnInfo(name = "col1")
    private String col1; 

但在您的迁移查询中,您可能会将col1 添加为INTEGER

从你的错误:

预期

columns=col1=Columnname='col1', type='TEXT', notNull=false, primaryKeyPosition=0

找到

columns=col1=Columnname='col1', type='INTEGER', notNull=false, primaryKeyPosition=0

解决方案:将迁移查询更改为:

ALTER TABLE 'YOUR_TABLE' 添加列 'col1' 文本

它会解决你的问题。

谢谢:)

【讨论】:

以上是关于Room Persistence Library:迁移过程中的奇怪错误的主要内容,如果未能解决你的问题,请参考以下文章

Room Persistence Library:迁移过程中的奇怪错误

从 SQLite 迁移到 Android Room Persistence Library

查看使用 Room Persistence Library 创建的数据库的内容

如何使用 Android Room Persistence Library 将 Column 注释为 NOT NULL

Android Room Persistence Library - 如何查找 ID 列表中包含 ID 的实体?

无法导入 android.arch.persistence.room.testing.MigrationTestHelper