Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • 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?
like image 763
Marcel50506 Avatar asked Jun 06 '16 11:06

Marcel50506


1 Answers

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.

like image 66
Tim Avatar answered Nov 14 '22 22:11

Tim