领域 android:无法将主键从 0.82.2 迁移到 0.86.0,因为字段支持 null

Realm android: Cant migrate primarykey from 0.82.2 to 0.86.0 because of field supporting null

我有一个 table,在 0.82.2 android 应用程序中有一个主键,具有以下字段:

// Each uid is generated using UUID strings:
@PrimaryKey
private String uid;

今天我已经更新到 Realm 0.86.0 以获得新的迁移 api(因为我添加了另一个 table 并想迁移现有的用户数据)。

但是,似乎 0.82.2 领域文件中的现有数据允许主键 uid 可以为空(当我 运行 应用程序没有对 uid 字段进行任何迁移时,领域告诉我这一点。

因此,我尝试创建一个名为 'id' 的新主键字段,然后使用以下代码迁移非空值:

dogSchema.removePrimaryKey();
dogSchema.addField("id", String.class, FieldAttribute.PRIMARY_KEY) 
                    .transform(new RealmObjectSchema.Function() {
                        @Override
                        public void apply(DynamicRealmObject obj) {

                            String oldUid = obj.getString("uid");

                            // Bring over any non null uids, generate new id to replace nulls
                            if (oldUid == null || oldUid.equals("")) {

                                // Null, so generate one as primarykey doesnt allow nulls:
                                String newUid = RealmUtils.generateUID();
                                Log.d(TAG, "### New filler dog uid = " + newUid);
                                obj.setString("id", newUid);
                            } else {
                                Log.d(TAG, "### Old dog uid = " + oldUid);
                                obj.setString("id", oldUid);

                            }
                        }
                    });

            dogSchema.removeField("uid");

但是,在迁移 运行s 之后,Realm 抛出异常说明:字段 'id' 不能是主键,因为现有的领域文件已经包含重复数据。尽管我可以看到每个 ID 值都不同。

如果我将 id 的 addfield 行更改为没有 PrimaryKey 属性(见下文),我会更进一步,但遇到另一个异常说 id 不能是主键,大概是因为我的模型有 @PrimaryKey 注释。

dogSchema.addField("id", String.class)

如何将主键迁移到 Realm 0.86.0?

感谢@Christian Melchior 在领域 java github 问题页面 (https://github.com/realm/realm-java/issues/1902) 上的帮助,我设法将旧模式主键迁移到领域 0.86.0:

结束代码是(注意缺少 'setNullable()' 调用)

"If your current uid field might contain null values you should be able to do it like this (without needing an additional field):"

  dogSchema.transform(new RealmObjectSchema.Function() {
        @Override
        public void apply(DynamicRealmObject obj) {
            String oldUid = obj.getString("uid");
            // Bring over any non null uids, generate new id to replace nulls
            if (oldUid == null || oldUid.equals("")) {
                // Null, so generate one as primarykey doesnt allow nulls:
                String newUid = RealmUtils.generateUID();
                Log.d(TAG, "### New filler dog uid = " + newUid);
                obj.setString("uid", newUid);
            } else {
                Log.d(TAG, "### Old dog uid = " + oldUid);
                obj.setString("uid", oldUid);
            }
        }
    });