Create and add object to RealmList in RealmMigration
Asked Answered
W

1

7

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:

  • In the line obj.getList("machineIds").add(realmLong);, I get the error that this function expects a DynamicRealmObject, not a RealmLong. How can I add a RealmLong to this list?
  • (Bonus question) Is this the correct and best approach to this migration problem?
Wolfson answered 6/6, 2016 at 11:44 Comment(0)
D
8

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.

Dirt answered 6/6, 2016 at 11:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.