Marcel50506
Marcel50506

Reputation: 1300

Create and add object to RealmList in RealmMigration

In my current app, I have a HolderObject (which extends RealmObject) with a long 'machineId'. In a new version of the app, this HolderObject will be able to contain more machines, in the form of a RealmList. See the classes below:

Old object:

public class HolderObject extends RealmObject{
    private long machineId;
    //.. getters and setters
}

New object:

public class HolderObject extends RealmObject{
    private RealmList<RealmLong> machineIds;
    //.. getters and setters
}

In which RealmLong is as follows:

public class RealmLong extends RealmObject {
    private long val;
    //.. getters and setters
}

To migrate all old HolderObjects to the new objects, I use my custom RealmMigration. This is as follows:

public class CustomRealmMigration implements RealmMigration {
    @Override
    public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
        RealmSchema schema = realm.getSchema();

        schema.get("HolderObject")
                .addRealmListField("machineIds", schema.get("RealmLong"))
                .transform(new RealmObjectSchema.Function() {
                    @Override
                    public void apply(DynamicRealmObject obj) {
                        Realm realm = Realm.getDefaultInstance();
                        realm.beginTransaction();
                        RealmLong realmLong = realm.createObject(RealmLong.class);
                        realmLong.setVal(obj.getLong("machineId"));
                        obj.getList("machineIds").add(realmLong);
                        realm.commitTransaction();
                        realm.close();
                    }
                });
    }
}

Question:

Upvotes: 7

Views: 2521

Answers (1)

Tim
Tim

Reputation: 43384

Do it like this:

schema.get("HolderObject")
        .addRealmListField("machineIds", schema.get("RealmLong"))
        .transform(new RealmObjectSchema.Function() {
            @Override
            public void apply(DynamicRealmObject obj) {
                DynamicRealmObject realmLong = realm.createObject("RealmLong");
                realmLong.setLong("val", obj.getLong("machineId"));
                obj.getList("machineIds").add(realmLong);
            }
        })
        .removeField("machineId");

The realmLong object you create has to be a DynamicRealmObject.
Also don't forget to remove the old field after the transformation.

Note that migrations are already wrapped in a transaction, you do not need to instantiate a realm object and execute a transaction yourself.

(Bonus question) Is this the correct and best approach to this migration problem?

Idea is good, execution is not. See above.

For additional information about migrations, see this example on github, and the docs of course.

Upvotes: 8

Related Questions