是否可以将具有不同 ID 的同一个 RealmObject 实例重用于写入事务中的 save/update 个多个对象?

Is it possible to reuse the same RealmObject instance with different IDs to save/update multiple objects in a write transaction?

目前,我们正在为我们想要保存在映射器中的每个 RealmObject 创建一个新实例 class。

@Override
public Person toRealmObject(Realm realm, PersonXML businessObject) {
    Person person = new Person();
    person.setId(businessObject.getId());
    person.setName(businessObject.getName());
    return person;
}

当我们创建一个新的时,我们将其收集到一个列表中。

@Override
public void populateRealmListWithMappedModel(Realm realm, RealmList<Person> realmList, PersonsXML personXML) {
    for(PersonXML personXML : personXML.getPersons()) {
        realmList.add(personMapper.toRealmObject(realm, personXML));
    }
}

/*next the following happens:*/
//realm.beginTransaction();
//personRepository.saveOrUpdate(realm, list);
//realm.commitTransaction();

然后我们保存列表。

@Override
public RealmList<T> saveOrUpdate(Realm realm, RealmList<T> list) {
    RealmList<T> realmList = new RealmList<T>();
    for(T t : realm.copyToRealmOrUpdate(list)) {
        realmList.add(t);
    }
    return realmList;
}

问题是,是否可能出现以下情况,我可以重新使用相同的 Person 对象并更改其值以将我创建的对象指定给 Realm想要保存,但没有与之关联的整个对象?

就像这样:

@Override
public Person toRealmObject(Realm realm, PersonXML businessObject, Person person) {
    person.setId(businessObject.getId());
    person.setName(businessObject.getName());
    return person;
}

然后

@Override
public void writeObjectsToRealm(Realm realm, PersonsXML personXML) {
    realm.beginTransaction();
    Person person = new Person();
    for(PersonXML personXML : personXML.getPersons()) {
        person = personMapper.toRealmObject(realm, personXML, person));
        personRepository.saveOrUpdate(person);
    }
    realm.closeTransaction();
}

这个方法在哪里

@Override
public T saveOrUpdate(Realm realm, T t) {
    return realm.copyToRealmOrUpdate(t);
}

我问这个是因为重写体系结构以使用以下内容需要重写我拥有的每个 populateRealmListWithMappedModel() 方法,如果它不起作用,那会有点令人担忧。所以我很好奇它在理论上是否有效。

基本上简短的问题是,如果我在 realmObject 上调用 copyToRealmOrUpdate(t),并更改其 id 和数据,并一次又一次地保存同一个对象,写入事务会成功吗?

是的,您可以重新使用用作 copyToRealm 输入的对象。我们正在创建您的输入对象的副本,但不会以任何方式更改原始对象,因此像您正在做的那样重用该对象应该可行,并且还会减少 GC 必须完成的工作量。

Person javaPerson = new Person();
Person realmPerson = realm.copyToRealm(javaPerson);

// The following is true
assertTrue(javaPerson != realmPerson)
assertFalse(javaPerson.equals(realmPerson))
assertFalse(realmPerson.equals(javaPerson))

是的,成功了。

@Override
public void persist(Realm realm, SchedulesXML schedulesXML) {
    Schedule defaultSchedule = new Schedule();
    if(schedulesXML.getSchedules() != null) {
        realm.beginTransaction();
        for(SchedulesByChannelXML schedulesByChannelXML : schedulesXML.getSchedules()) {
            Channel channel = channelRepository.findOne(realm, schedulesByChannelXML.getChannelId());
            if(channel == null) {
                Log.w(TAG,
                        "The channel [" + schedulesByChannelXML.getChannelId() + "] could not be found in Realm!");
            }
            for(ScheduleForChannelXML scheduleForChannelXML : schedulesByChannelXML.getSchedules()) {
                defaultSchedule = scheduleMapper.toRealmObject(realm, scheduleForChannelXML, defaultSchedule);
                defaultSchedule.setChannel(channel);
                defaultSchedule.setChannelId(schedulesByChannelXML.getChannelId());
                boolean isInRealm = scheduleRepository.findOne(realm,
                        scheduleForChannelXML.getScheduleId()) != null;
                Schedule savedSchedule = scheduleRepository.saveOrUpdate(realm, defaultSchedule);
                if(!isInRealm) {
                    if(channel != null) {
                        channel.getSchedules().add(savedSchedule);
                    }
                }
            }
        }
        realm.commitTransaction();
    }
}

不再每次保存一批计划时创建 150 个计划,现在我每批只创建一个,而且它完美无缺。