CopyToRealm - 值已存在:null

时间:2016-06-29 15:31:25

标签: android retrofit realm

我从我的API中获得了大量用户。当我获得这些用户时,我删除任何现有用户并保存新用户。我正在使用Android Priority Job QueueRetrofit2来提出请求。

    if (searchResponse != null && searchResponse.getUsers() != null)
    {
        realm.executeTransaction(new Realm.Transaction()
        {
            @Override
            public void execute(Realm realm)
            {
                RealmResults<User> users = realm.where(User.class).equalTo("isOwnUser", false).findAll();
                users.deleteAllFromRealm();
                realm.copyToRealm(searchResponse.getUsers());
            }
        });
    }

所有用户都拥有从API填充的ID。但当我执行realm.copyToRealm(searchResponse.getUsers());时,我得到:io.realm.exceptions.RealmPrimaryKeyConstraintException: Value already exists: null

2 个答案:

答案 0 :(得分:3)

我使用这种方法来解决这个问题

realm.copyToRealmOrUpdate(searchResponse.getUsers())

答案 1 :(得分:1)

接受的答案有效但却是一个糟糕的解决方案,因为它隐藏了你的根本问题:

您拥有主键字段设置为null的对象。它可能是一个扩展RealmObject的对象,位于User对象中,未使用@Ignore注释。

以下是可能发生的事情的一个例子:

假设您的User对象包含一个对象ContactInfo,该对象的字段phoneNumber被设置为主键。

某些User个对象将phoneNumber ContactInfo字段设置为空。

当您使用copyToRealm时,Realm会尝试添加所有User个对象以及这些ContactInfo个对象包含的所有User个对象。其中一些ContactInfo对象将主键字段设置为null。这将首次起作用,因为StringByteShortIntegerLong类型的主键字段可以为空。但是当你第二次这样做时,你将破坏主键约束。

使用copyToRealmOrUpdate将起作用,因为您只需更新现有的ContactInfo对象,并将主键设置为null。你可以看到这不是你想要做的,你需要确保你添加到Realm的所有对象都有正确的主键。