Search code examples
androiddatabaserealmrealm-mobile-platformrealm-list

Realm Delete Orphaned Objects in an Efficient Way


I have a class BeaconBase containing list of BeaconData.

public class BeaconBase extends RealmObject {

    @PrimaryKey
    private Integer checkInID;

    @SerializedName("beacons")
    @Expose
    private RealmList<BeaconData> beacons;
}

public class BeaconData extends RealmObject {

    @SerializedName("scanId")
    @Expose
    private String scanId;

    @SerializedName("distance")
    @Expose
    private String distance;

}

BeaconData will usually be huge. May be around 100000 rows per hour. How do i efficiently delete BeaconData when i delete related BeaconBase record?

I have Primary Key only in BeaconBase.

So when i delete BeaconBase record, thousands of BeaconData records are being orphaned. How can i efficiently handle this situation?


Solution

  • try(Realm r = Realm.getDefaultInstance)) {
        r.executeTransaction((realm) -> {
            RealmResults<BeaconBase> beaconsToDelete = realm.where(BeaconBase.class)./*query here*/.findAll();
            for(int i = beaconsToDelete.size() - 1; i >= 0; i--) {
                BeaconBase beaconBase = beaconsToDelete.get(i);
                beaconBase.getBeacons().deleteAllFromRealm();
                beaconBase.deleteFromRealm();
            }
        });
    }
    

    Although to be slightly more of use, you could also do this:

    public class BeaconBase extends RealmObject {
    
        @PrimaryKey
        private Integer checkInID;
    
        @SerializedName("beacons")
        @Expose
        private RealmList<BeaconData> beacons;
    }
    
    public class BeaconData extends RealmObject {
    
        @SerializedName("scanId")
        @Expose
        private String scanId;
    
        @SerializedName("distance")
        @Expose
        private String distance;
    
        @LinkingObjects("beacons")
        private final RealmResults<BeaconBase> beaconDataOf = null;
    }
    
    try(Realm r = Realm.getDefaultInstance)) {
        r.executeTransaction((realm) -> {
            realm.where(BeaconBase.class)./*query here*/.findAll().deleteAllFromRealm();
            realm.where(BeaconData.class).isEmpty("beaconDataOf").findAll().deleteAllFromRealm();
        });
    }