Строка автоматически удаляется в Android RealmDB после добавления новой записи в связанную таблицу?

Контекст: изолироватьМестоположение и Восприимчивость (1-много) имеют отношение один ко многим, а также Лекарственное средство и Восприимчивость (1-много). Все они являются RealmObjects и IsolateLocation, а также Drug содержат RealmList of Susceptibilities. Восприимчивость создается для всех препаратов в каждом месте локализации, затем эта восприимчивость добавляется в соответствующий список восприимчивости изолятаМестоположение и список восприимчивости к лекарствам.

Проблема: первый объект Susceptibility правильно добавляется в списки в обеих моделях (Drug и IsolateLocation), но следующий созданный объект Susceptibility правильно добавляется в модель Drug сразу после его добавления в модель Susceptibility. list предыдущая запись в списке IsolateLocation Susceptibility удаляется. Таким образом, в конце чувствительность к лекарственным препаратам верна с несколькими восприимчивостями, но список восприимчивости IsolateLocation имеет только 1.

Необработанные данные: https://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();
}

person Zee    schedule 25.01.2017    source источник
comment
Вы должны добавлять элементы в 1 транзакцию, а не N транзакций на N элемент.   -  person EpicPandaForce    schedule 26.01.2017


Ответы (3)


Вам нужно вставить управляемая областью Susceptibility экземпляров в drugEntry.getSusceptibilities() и isolateLocationEntry.getSusceptibilities(). То есть вам нужно создать новый экземпляр Susceptibility по методу realm.createObject():

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(), прежде чем вставлять его в 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();
}

Дополнительную информацию о создании управляемых объектов вы можете найти в официальной документации и этот ответ.

person XIII-th    schedule 26.01.2017

Это потому, что вы должны вставлять вот так

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();
person EpicPandaForce    schedule 26.01.2017

Я нашел решение до того, как были опубликованы ответы выше, не уверен, что это правильный способ сделать это.

Я не сохранял никаких данных, пока не разобрал все данные в память List<IsolateLocation> isolateLocationList и List<Drug> drugList, а затем не создал управляемый объект области для Susceptibility. Добавил List<Susceptibility> susceptibilitiesList к drugList и isolateLocationList и вызвал этот метод

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

Вторая строка — copyToRealmOrUpdate, потому что некоторые лекарства были сохранены в области после выполнения первой строки, что является результатом отношений между моделями, но во второй строке есть все полные данные о наркотиках, поэтому, если запись уже существует обновить его.

person Zee    schedule 26.01.2017
comment
Я удалил первичный ключ из Susceptibility - person Zee; 26.01.2017