Reputation: 2564
I'm using Realms as a database in Android app. Works fine, but I've added a new label in my user model and I'm getting the error that I need to migrate my schema:
java.lang.RuntimeException: Unable to create application com.apelucy.apelucy.app.base.MyApplication: io.realm.exceptions.RealmMigrationNeededException: Migration is required due to the following errors:
- Property 'User.testRealm' has been added.
How can I do the migration? I've found other solutions here but I can't implement them in my code. I can't use a solution of delete and install the app. I now that work in development, but I need to update the app in production.
My UserRespository class:
public class UserRepository {
private static UserRepository sInstance = null;
private Context mContext = null;
public static UserRepository getInstance(Context context) {
if (sInstance == null) {
sInstance = new UserRepository();
sInstance.mContext = context;
}
return sInstance;
}
// DATABASE Methods
public void storeUser(final User user) {
AppSingleton.getInstance().setUser(user);
Realm realm = null;
try {
realm = Realm.getDefaultInstance();
realm.executeTransaction(realm1 -> realm1.insertOrUpdate(user));
} finally {
if (realm != null) {
realm.close();
}
}
}
public User retrieveUser() {
Realm realm = null;
User user = null;
try {
realm = Realm.getDefaultInstance();
User userRealmResult = realm.where(User.class)
.findFirst();
if (userRealmResult != null) {
user = realm.copyFromRealm(userRealmResult);
}
} finally {
if (realm != null) {
realm.close();
}
}
return user;
}
public void clearUser() {
// Clear Database objects
Realm realm = null;
try {
realm = Realm.getDefaultInstance();
realm.executeTransaction(realm1 -> realm1.delete(User.class));
} finally {
if (realm != null) {
realm.close();
}
}
}
}
Init realm in my Application:
Realm.init(this);
My model change:
@SerializedName("test")
@Expose
private String testRealm;
Upvotes: 13
Views: 5736
Reputation: 81539
Migrations allow you to modify the schema of the application, which means that it lets you add, remove, rename tables/fields in the Realm schema. If you change a RealmModel class, then you must write the migration that will map the existing Realm file to reflect the new model classes.
RealmConfiguration config = new RealmConfiguration.Builder()
.schemaVersion(1)
.migration(new MyMigration())
.build();
Realm.setDefaultConfiguration(config);
The default schema version is 0.
Migrations are fairly straightforward:
you must increment the schema version, so Realm knows you want to increment the schema's version to a specific number
you must supply a migration that will handle the change from one version to another
Migrations describe the operations to do when you need to go from one schema version to another:
public class MyMigration implements RealmMigration {
@Override
public void migrate(final DynamicRealm realm, long oldVersion, long newVersion) {
RealmSchema schema = realm.getSchema();
// Migrate from version 0 to version 1
if (oldVersion == 0) {
RealmObjectSchema userSchema = schema.get("User");
userSchema.addField("testRealm", String.class);
oldVersion++;
}
if (oldVersion == 1) { // ...
// ...
}
}
@Override
public int hashCode() { return MyMigration.class.hashCode(); }
@Override
public boolean equals(Object object) { return object != null && object instanceof MyMigration; }
}
Upvotes: 11
Reputation: 33
Add this in your Application file. This will Realm to delete everything if you add a new table to a column.
RealmConfiguration config = new RealmConfiguration.Builder().name("dbname.realm")
.deleteRealmIfMigrationNeeded()
.build();
Realm.setDefaultConfiguration(config);
Upvotes: -2