Migration Error: How to migrate Indices and Typeconverters?

Migration Error: How to migrate Indices and Typeconverters?

我有一个简单的驱动程序class:

@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);
 }
}

我的TypeConverterclass:

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();
}
}

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

@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 异常错误之一:

我用黄色标记了不匹配的列。正如您所看到的,Date TypeConverter 没有正确迁移,即使我说日期的数据类型为 NUMERIC 并且出于某种原因,任何空间都会创建一个 indices column,它不会迁移,即使我添加了 indices 注释我的 Driver class。我错过了什么?

迁移可能是 .... 我尝试了您的代码并发现了问题:

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. 您需要将日期数据类型更改为 INTEGER 而不是 NUMERIC,因为 SQLLITE 需要 INTEGER。