0

I have this classes

class Student extends RealmObject {
    public String code;
    public String name;
    public String email;
    public Course course;
}

class Course extends RealmObject {
    public String code;
    public String name;
}

class Sync {
    // ...
    // To sync data I am using retrofit, look the method to update course
    public void onResponse(Call<...> call, Response<...> response) {
        if (response.isSuccessful()) {
            realm.executeTransactionAsync(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                    realm.delete(Course.class);
                    realm.copyToRealm(response.body());
                }
            });
        }
    }
}

After call Sync to update Courses, all Student object has its course setting to null, this is expected behavior after called realm delete? Even after table is populated again, the course on Student is still null.

Today I made this change on the code:

class Course extends RealmObject {
    @PrimaryKey
    public String code;
    public String name;
}

class Sync {
    // ...
    // To sync data I am using retrofit, look the method to update course
    public void onResponse(Call<...> call, Response<...> response) {
        if (response.isSuccessful()) {
            realm.executeTransactionAsync(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                    realm.copyToRealmOrUpdate(response.body());
                }
            });
        }
    }
}

I made this too late to avoid delete the courses.

There is something that can I do to recovery the references courses and set it again to student?

Thank you.

1 Answers1

2

This is expected behavior, because you invalidate the object links by deleting the objects you are pointing to.

To restore them, you would have to set the links again.


Another solution would be to not delete courses that you still need. This would be done if you annotate code with @PrimaryKey, that way you would "update" courses that are already in. Then the problem would be removing courses/students no longer in the response, but there are solutions ready-made for that.

public class Robject extends RealmObject {
    @PrimaryKey
    private String code;

    @Index
    private String name;

    //...

    @Index
    private boolean isBeingSaved;

    //getters, setters
}

And

// background thread
Realm realm = null;
try {
    realm = Realm.getDefaultInstance();
    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            Robject robject = new Robject();
            for(Some some : somethings) {
                robject.set(some....);
                realm.insertOrUpdate(robject);
            }
            realm.where(Robject.class)
                 .equalTo(Robject.IS_BEING_SAVED, false) // compile 'dk.ilios:realmfieldnameshelper:1.1.0'
                 .findAll()
                 .deleteAllFromRealm(); // delete all non-saved data
            for(Robject robject : realm.where(Robject.class).findAll()) { // realm 0.89.0+
                robject.setIsBeingSaved(false); // reset all save state
            }
        }
    });
} finally {
    if(realm != null) {
        realm.close();
    }
}
Community
  • 1
  • 1
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • Thank you. I thought Realm keeps some kind of id in the Student even after delete course. And the references could be recovered after table were populated again. I am following your tips to use annotation `@PrimaryKey` and now I am avoiding delete object from realm. I will close this like solved. – diegofesanto Nov 29 '16 at 15:23