Я понял, что моя стратегия миграции базы данных неверна, и переписал ее. На данный момент это выглядит так:
@Database(entities = {SaveData.class, Achievement.class}, version = 2, exportSchema = false)
@TypeConverters(MapConverters.class)
public abstract class AppDatabase extends RoomDatabase {
public abstract SaveDataDAO saveDataDAO();
public abstract AchievementDAO achievementDAO();
}
Со вспомогательным классом, который выглядит так:
public class AppDatabaseHelper {
private static AppDatabase db;
private AppDatabaseHelper() {
// static utility
}
private static final Migration MIGRATION_1_2 =
new Migration(1, 2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
Set<AchievementType> achievementTypes = EnumSet.allOf(AchievementType.class);
String values = achievementTypes.stream().map(AppDatabaseHelper::createRow).collect(Collectors.joining(", "));
String fullQuery = "INSERT OR IGNORE INTO Achievement(name, current, total) VALUES " + values;
database.execSQL(fullQuery);
}
};
private static String createRow(AchievementType achievementType) {
String name = achievementType.name();
int total = achievementType.getTotal();
return String.format("('%s',0,%s)", name, total);
}
public static AppDatabase getDatabase(Context context) {
if (db == null) {
db = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class, "game")
.addMigrations(MIGRATION_1_2)
.build();
}
return db;
}
}
Когда я удаляю базу данных и запускаю приложение, доступ к базе данных для при первом запуске перенос не выполняется должным образом. Вместо этого я вижу, что версия базы данных внутри SQLLiteOpenHelper.java
равна 0, пытаясь перейти на 2. Из-за этого c часть вспомогательного класса Android:
db.beginTransaction();
try {
if (version == 0) {
onCreate(db);
} else {
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
внутри метод getDatabaseLocked
, я вижу, что он не будет запускать никаких миграций, если он начинается с версии 0, а вместо этого просто установит версию, на которую вы мигрируете.
Это поведение не имеют какой-то смысл для меня, поэтому я предполагаю, что что-то упускаю. Я пробовал хитрый обходной путь, просто принудительно переходя с go на 1 (путем создания другого класса RoomDatabase
), а затем запускал вышеуказанный, который работает. Я также пробовал вручную установить версию базы данных равной 1, но это тоже не кажется правильным решением.
Сообщите мне, если вам понадобится больше кода для контекста