【问题标题】:Room Database Migration doesn't properly handle New table creation房间数据库迁移无法正确处理新表创建
【发布时间】:2019-09-18 18:05:16
【问题描述】:

日志包含:

java.lang.IllegalStateException: Migration didn't properly handle broadBandPlans(duleaf.duapp.splash.data.local.models.FixedPlanLocal).

*Expected:
TableInfo{name='broadBandPlans', columns={speed=Column{name='speed', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, prodID=Column{name='prodID', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1}}, foreignKeys=[], indices=[]}*

*Found:
TableInfo{name='broadBandPlans', columns={prodID=Column{name='prodID', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1}, speed=Column{name='speed', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0}}, foreignKeys=[], indices=[]}*

下面是 FixedPlanLocal 类,有人可以在这里指导我为什么 Room 期望速度作为第一列,然后是 prodID,我应该如何解决这个问题?

@Entity(tableName = "broadBandPlans")
public class FixedPlanLocal {

    @ColumnInfo(name = "prodID")
    @PrimaryKey
    @NonNull
    String prodID;

    @ColumnInfo(name = "speed")
    String speed;


    public FixedPlanLocal(@NonNull String prodID, String speed) {
        this.prodID = prodID;
        this.speed = speed;
    }

    @NonNull
    public String getProdID() {
        return prodID;
    }

    public void setProdID(@NonNull String prodID) {
        this.prodID = prodID;
    }

    public String getSpeed() {
        return speed;
    }

    public void setSpeed(String speed) {
        this.speed = speed;
    }

    @Override
    public boolean equals(Object obj) {
        return this.prodID.equals(((FixedPlanLocal) obj).prodID);
    }
}
, 

【问题讨论】:

    标签: android database sqlite android-room


    【解决方案1】:

    您已经使用 NOT NULL 约束定义了表的 speed 列,因此您需要在 speed 列的实体中使用 @NonNull:-

    • 预期是根据实体
    • 发现如表

    而不是:-

    public String getSpeed() {
        return speed;
    }
    

    使用:-

    @NonNull
    public String getSpeed() {
        return speed;
    }
    

    列顺序无关紧要,Room 似乎一直没有按预期对它们进行排序(即,不按照预期列表的表或实体)

    重要的是值必须在预期值和找到值之间保持一致。

    在您的情况下,速度列的实体(预期)和表(找到)是:-

    name='speed', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0
    name='speed', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0
    

    您可以很容易地看到 notNull 对于实体​​是 false(@NotNull 未编码)但对于表是 true

    解决方法是将@NotNull 添加到实体(如上)或更改表定义,以使速度列没有 NOT NULL 约束。

    • 注意,在某些情况下,例如在实体中使用 java 主要类型时,暗示 @NotNull(在这种情况下,您必须更改表(或使用等效对象而不是 java 主要类型,例如使用 Integer 而不是 int))李>

    【讨论】:

    • 感谢 Mike,虽然我不明白为什么 Speed Column 应为 NotNull,但下面的代码已修复它,我仅将 prodID 定义为 Notnull。 @NonNull @ColumnInfo(name = "speed") 字符串速度;
    • @rkdroid with ROOM,表必须符合实体的预期,否则您会得到不匹配和预期/发现问题,因为在运行时构建数据库时,将根据实体与表进行比较时间。通常,实体驱动基础表的创建,但在迁移时,更改不是由 Room 进行的,而是由迁移代码进行的。
    猜你喜欢
    • 1970-01-01
    • 2019-12-03
    • 1970-01-01
    • 2019-04-23
    • 2021-05-27
    • 1970-01-01
    • 2019-02-13
    • 2018-12-03
    • 2021-08-13
    相关资源
    最近更新 更多