0

Context: isolateLocation and Susceptibilities (1-many) have a one to many relationship as well as Drug and Susceptibilities (1-many). All are RealmObjects and IsolateLocation as well as Drug contains RealmList of Susceptibilities. A Susceptibility is created for all drugs in every isolateLocation, this Susceptibility is then added to the corresponding IsolateLocation Susceptibility list and Drug Susceptibility list.

Problem: The first Susceptibility object is added correctly to lists in both the models (Drug & IsolateLocation) but the next Susceptibility that is created is correctly added to the Drug model, immediately after adding it to the Drug Susceptibility list, the previous entry in the IsolateLocation Susceptibility list is deleted. So at the end Drug Susceptibility is correct with multiple Susceptibilities but IsolateLocation Susceptibility list only has 1.

Raw Data: https://i.stack.imgur.com/gG2RF.jpg

Code:

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();
}
Zee
  • 103
  • 1
  • 1
  • 8

3 Answers3

0

You need insert realm managed Susceptibility instances to drugEntry.getSusceptibilities() and isolateLocationEntry.getSusceptibilities(). I.e, you need to create new Susceptibility instance by method 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();
}

Or, you need insert unmanaged instance to realm by call realm.copyToRealm() before insert it to drugEntry.getSusceptibilities() and 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();
}

More info about managed object creation you can read official documentation and this answer.

Community
  • 1
  • 1
Sergei Bubenshchikov
  • 5,275
  • 3
  • 33
  • 60
0

That's because you're supposed to insert like this

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();
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
0

I figured out a solution before the answers above were posted, not sure if its the right way to do it.

I didn't persist any data until I parsed out all the data into in-memory List<IsolateLocation> isolateLocationList and List<Drug> drugList, then without creating a realm managed object for Susceptibility. Added the List<Susceptibility> susceptibilitiesList to both the drugList and isolateLocationList and called this method

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

The second line is copyToRealmOrUpdate is because some Drugs were saved into realm after the execution of the first line which is as a result of the relationship between the models, but the second line has all the complete data about the drugs so, if an entry already exists update it.

Zee
  • 103
  • 1
  • 1
  • 8