【问题标题】:Migration Error: How to migrate Indices and Typeconverters?迁移错误:如何迁移索引和类型转换器?
【发布时间】:2021-02-13 21:21:09
【问题描述】:

我有一个简单的 Driver 类:

@Entity(tableName = "Driver",
    indices = {@Index(value = {"driverName"},unique = true), @Index(value = {"drivingLicNum"},unique = true)}
    )
public class Driver {

 @PrimaryKey(autoGenerate = true)
 @ColumnInfo(name = "id")
 @NotNull
 private int id;

 @ColumnInfo(name = "firstName")
 @NotNull
 private String firstName;

 @ColumnInfo(name = "lastName")
 @NotNull
 private String lastName;

 @ColumnInfo(name = "driverName")
 @NotNull
 private String driverName;

 //optionale Parameter
 @ColumnInfo(name = "birthDate")
 @TypeConverters(Converters.class)
 private Date birthDate;

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


 @ColumnInfo(name = "drivingLicExpDate")
 @TypeConverters(Converters.class)
 private Date drivingLicExpDate;

 @ColumnInfo(name = "gender")
 @TypeConverters(Converters.class)
 private Gender gender;

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

 @ColumnInfo(name = "licCategory")
 @TypeConverters(Converters.class)
 private ArrayList<LicenceCategory> licCategory;

 @ColumnInfo(name = "isActive",  defaultValue = "1")
 @NotNull
 private boolean isActive;

 @ColumnInfo(name = "profilePic")
 private byte[] profilePic;

 public Driver(@NotNull String firstName, @NotNull String lastName, @NotNull String driverName) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.driverName = driverName;
    licCategory = new ArrayList<>();
    setIsActive(true);
 }
}

我的TypeConverter 班级:

public final class Converters {

private static Gson gson = new Gson();

@TypeConverter
public static ArrayList<LicenceCategory> fromStringToLicenceCategories(String value) {
    Type listType = new TypeToken<ArrayList<LicenceCategory>>() {}.getType();
    return gson.fromJson(value, listType);
}
@TypeConverter
public static String fromLicenceCategoriesToString(ArrayList<LicenceCategory> list) {
    return gson.toJson(list);
}

@TypeConverter
public static Gender fromStringToGender(String value) {
    Type listType = new TypeToken<Gender>() {}.getType();
    return gson.fromJson(value, listType);
}

@TypeConverter
public static String fromGenderToString(Gender gender) {
    return gson.toJson(gender);
}

@TypeConverter
public static Date fromTimestampToDate(Long value) {
    return value == null ? null : new Date(value);
}

@TypeConverter
public static Long fromDateToTimestamp(Date date) {
    return date == null ? null : date.getTime();
}
}

最后但同样重要的是,我的数据库类中的迁移代码:

@Database(entities = {Driver.class, User.class}, version = 2, exportSchema = false)
@TypeConverters({Converters.class})
public abstract class CarServiceDB  extends RoomDatabase{

private static CarServiceDB instance;

public static CarServiceDB getDatabase(Context context) {
    if (instance == null) {

        Migration migration = new Migration(1, 2) {
            @Override
            public void migrate(@NonNull SupportSQLiteDatabase database) {
                database.execSQL("CREATE TABLE IF NOT EXISTS Driver (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, firstName TEXT NOT NULL, " +
                        "lastName TEXT NOT NULL, driverName TEXT NOT NULL UNIQUE, birthDate NUMERIC, drivingLicNum INTEGER UNIQUE, drivingLicExpDate NUMERIC, " +
                        "gender TEXT CHECK(gender = \"MALE\" or gender = \"FEMALE\" or gender = \"UNKNOWN\"), " +
                        "issuingAuthority TEXT, licCategory TEXT, isActive INTEGER NOT NULL DEFAULT 1 CHECK(isActive IN (0,1)),profilePic BLOB)");
            }
        };

        instance = Room.databaseBuilder(context, CarServiceDB.class, "mycardatabase.db").addMigrations(migration).createFromAsset("databases/mycardatabase.db").build();


    }
    return instance;
}
public abstract UserDao userDao();
}

但是,我得到了可能是最烦人的 Room 异常错误之一:

我将不匹配的列标记为黄色。如您所见,日期类型转换器未正确迁移,即使我说日期的数据类型为NUMERIC,并且出于某种原因,房间会创建一个indices column,即使我添加了@987654329,它也不会迁移@ 注释我的 Driver 类。我错过了什么?

【问题讨论】:

    标签: android sqlite migration android-room indices


    【解决方案1】:

    迁移可能是一种痛苦...... 我尝试了您的代码,发现了问题:

    Migration migration = new Migration(1, 2) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
      database.execSQL("DROP TABLE IF EXISTS Driver");
      database.execSQL("CREATE TABLE IF NOT EXISTS Driver (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, firstName TEXT NOT NULL, " +
      "lastName TEXT NOT NULL, driverName TEXT UNIQUE NOT NULL , birthDate INTEGER, drivingLicNum TEXT UNIQUE, drivingLicExpDate INTEGER, " +
      "gender TEXT CHECK(gender = \"MALE\" or gender = \"FEMALE\" or gender = \"UNKNOWN\"), issuingAuthority TEXT, licCategory TEXT, isActive INTEGER NOT NULL DEFAULT 1 CHECK(isActive IN (0,1)),profilePic BLOB)");
    
      database.execSQL("CREATE UNIQUE INDEX index_Driver_drivingLicNum ON  Driver(drivingLicNum)");
      database.execSQL("CREATE UNIQUE INDEX index_Driver_driverName ON  Driver(driverName)");
    }
    

    我改变了什么?:

    1. 您需要为每个唯一列创建唯一索引
    2. 您需要将 Date 数据类型更改为 INTEGER 而不是 NUMERIC,因为 SQLLITE 需要一个 INTEGER。

    【讨论】:

      猜你喜欢
      • 2015-06-17
      • 1970-01-01
      • 2017-07-11
      • 2019-06-26
      • 1970-01-01
      • 2015-03-01
      • 2018-06-28
      • 2016-05-23
      • 1970-01-01
      相关资源
      最近更新 更多