在相关 table 中添加新条目后,android RealmDB 中的行自动删除了吗?

Row automatically deleted in android RealmDB after adding new entry in a related table?

上下文: isolateLocation 和敏感性(一对多)以及药物和敏感性(一对多)具有一对多关系。所有都是 RealmObjects 和 IsolateLocation 以及 Drug 包含 RealmList of Susceptibilities。为每个isolateLocation中的所有药物创建一个Susceptibility,然后将该Susceptibility添加到相应的IsolateLocation Susceptibility list和Drug Susceptibility list中。

问题:第一个 Susceptibility 对象被正确添加到两个模型(药物和 IsolateLocation)的列表中,但创建的下一个 Susceptibility 被正确添加到药物模型,将其添加到药物敏感性列表后,IsolateLocation 敏感性列表中的先前条目将立即被删除。所以最后药物敏感性对多个敏感性是正确的,但 IsolateLocation 敏感性列表只有 1.

原始数据: http://imgur.com/a/iTPY8

代码:

for (Drug drug : drugList){
    Susceptibility susceptibility = new Susceptibility();
    susceptibility.setId(UUID.randomUUID().toString());
    susceptibility.setDrug(drug);
    susceptibility.setReference(parsedCsv[drug.getId()+1]);
    susceptibility.setSusceptibilityValue(parsedCsv[drug.getId()]);
    susceptibility.setIsolateLocation(isolateLocation);
    addSusceptibilityToRealm(isolateLocation, drug, susceptibility);
    }


private void addSusceptibilityToRealm(IsolateLocation isolateLocation, Drug drug, Susceptibility susceptibility) {
    realm.beginTransaction();
    Drug drugEntry = realm.where(Drug.class).equalTo("id", drug.getId()).findFirst();
    drugEntry.getSusceptibilities().add(susceptibility);

    IsolateLocation isolateLocationEntry = realm.where(IsolateLocation.class).equalTo("id", isolateLocation.getId()).findFirst();
    isolateLocationEntry.getSusceptibilities().add(susceptibility);
    realm.commitTransaction();
}

您需要将 realm managed Susceptibility 个实例插入 drugEntry.getSusceptibilities()isolateLocationEntry.getSusceptibilities()。即,您需要通过 realm.createObject():

方法创建新的 Susceptibility 实例
for (Drug drug : drugList){
    String id = UUID.randomUUID().toString();
    realm.beginTransaction();
    // Create a new object
    Susceptibility susceptibility = realm.createObject(Susceptibility.class, id);
    /*
    setup properties of susceptibility instances
    ....
    */
    addSusceptibilityToRealm(isolateLocation, drug, susceptibility);
    realm.commitTransaction();
}

或者,您需要先通过调用 realm.copyToRealm()unmanaged 实例插入领域,然后再将其插入 drugEntry.getSusceptibilities()isolateLocationEntry.getSusceptibilities():

private void addSusceptibilityToRealm(IsolateLocation isolateLocation, Drug drug, Susceptibility susceptibility) {
    realm.beginTransaction();
    // Copy the object to Realm. Any further changes must happen on susceptibility
    Susceptibility susceptibility = realm.copyToRealm(susceptibility);

    Drug drugEntry = realm.where(Drug.class).equalTo("id", drug.getId()).findFirst();
    drugEntry.getSusceptibilities().add(susceptibility);

    IsolateLocation isolateLocationEntry = realm.where(IsolateLocation.class).equalTo("id", isolateLocation.getId()).findFirst();
    isolateLocationEntry.getSusceptibilities().add(susceptibility);
    realm.commitTransaction();
}

有关 托管 对象创建的更多信息,您可以阅读 official documentation and this answer

那是因为你应该像这样插入

realm.beginTransaction();
for (Drug drug : drugList){
    Susceptibility susceptibility = realm.createObject(Susceptibility.class, UUID.randomUUID().toString());
    Drug drugEntry = realm.where(Drug.class).equalTo("id", drug.getId()).findFirst();
    susceptibility.setDrug(drugEntry);
    susceptibility.setReference(parsedCsv[drug.getId()+1]);
    susceptibility.setSusceptibilityValue(parsedCsv[drug.getId()]);
    susceptibility.setIsolateLocation(isolateLocation);
    drugEntry.getSusceptibilities().add(susceptibility);
    IsolateLocation isolateLocationEntry = realm.where(IsolateLocation.class).equalTo("id", isolateLocation.getId()).findFirst();
    isolateLocationEntry.getSusceptibilities().add(susceptibility);
    //addSusceptibilityToRealm(isolateLocation, drug, susceptibility);
}
realm.commitTransaction();

我在上面的答案发布之前想出了一个解决方案,不确定它是否是正确的方法。

在将所有数据解析为 in-memory List<IsolateLocation> isolateLocationListList<Drug> drugList 之前,我没有保留任何数据,然后没有为 Susceptibility 创建领域管理对象.将 List<Susceptibility> susceptibilitiesList 添加到 drugListisolateLocationList 并调用此方法

private void addDataToRealm() {
    realm.executeTransactionAsync(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            realm.copyToRealm(isolateLocationList);
            realm.copyToRealmOrUpdate(drugList);
        }
    });
}

第二行是 copyToRealmOrUpdate 是因为第一行执行后一些药物被保存到领域,这是模型之间关系的结果,但是第二行有关于药物的所有完整数据所以, 如果一个条目已经存在更新它。