androiddatabaserealmillegalstateexceptionstaledataexception

Realm crashes item deleted. But I do requery Realm first


I get back a response and I do this:

 if (jsonObject != null && jsonObject.has("results")) {
                try {
                    final JSONArray array = jsonObject.getJSONArray("results");
                    Realm realm = Realm.getInstance(PSApplicationClass.Config);
                    realm.executeTransaction(new Realm.Transaction() {
                        @Override
                        public void execute(Realm realm) {
                            try {
                                realm.delete(Beacon.class);
                                realm.createOrUpdateAllFromJson(Beacon.class, array);
                            } catch (Exception e) {
                                Log.e("", "error is: " + e.getMessage());
                            }
                            if (back != null)
                                back.onResponse("");
                        }
                    });
                    realm.close();
                } catch (Exception e) {
                    Log.e("", "error trying to fetch user beacons: " + e.getMessage());
                    if (back != null)
                        back.onResponse("");
                }
            }

This is in my Beacon.java model class. Now after that, in my Activity, I do this:

 public void setBeaconsInList() {
    Realm realm = Realm.getInstance(PSApplicationClass.Config);
    RealmResults<Beacon> beaconsResults = realm.where(Beacon.class).findAll();
    if (beaconsResults != null && beaconsResults.size() > 0) {
        for (Beacon beacon : beaconsResults) {
             for (Beacon beacon : beaconsResults) {
                if (!beacons.contains(beacon)) {
                    if (beacon.getUser_vehicle() != null) {
                        beacons.add(0, beacon);
                        userBeaconAdapter.addItemFirst(beacon);
                    } else {
                        beacons.add(beacon);
                        userBeaconAdapter.addItem(beacon);
                    }
                }
            }
        }
    }
    userBeaconAdapter.notifyDataSetChanged();
    realm.close();
}

I get this error:

10-16 17:39:09.527: E/AndroidRuntime(27720): java.lang.IllegalStateException: Object is no longer valid to operate on. Was it deleted by another thread?
10-16 17:39:09.527: E/AndroidRuntime(27720):    at io.realm.internal.UncheckedRow.nativeGetIndex(Native Method)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at io.realm.internal.UncheckedRow.getIndex(UncheckedRow.java:137)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at io.realm.BeaconRealmProxy.equals(BeaconRealmProxy.java:851)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at java.util.ArrayList.contains(ArrayList.java:339)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at nl.hgrams.passenger.activities.PSUserBeaconsActivity.setBeaconsInList(PSUserBeaconsActivity.java:144)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at nl.hgrams.passenger.activities.PSUserBeaconsActivity$2.onResponse(PSUserBeaconsActivity.java:126)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at nl.hgrams.passenger.model.vehicle.Beacon$1.onResponse(Beacon.java:117)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at nl.hgrams.passenger.utils.WSCalls$1.onResponse(WSCalls.java:98)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at nl.hgrams.passenger.utils.WSCalls$1.onResponse(WSCalls.java:77)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:90)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at android.os.Handler.handleCallback(Handler.java:739)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at android.os.Handler.dispatchMessage(Handler.java:95)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at android.os.Looper.loop(Looper.java:148)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at android.app.ActivityThread.main(ActivityThread.java:5417)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at java.lang.reflect.Method.invoke(Native Method)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
10-16 17:39:09.527: E/AndroidRuntime(27720):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Why does this happen? If I recreate my realm instance, and I requery, why does it return objects that where deleted? I just want to show the remaining objects.

If not, is there a different way, of checking and deleting the objects that were not updated from the server?


Solution

  • Thanks to Orlando's comment, I figured it out. my list was being compared with the objects inside my adapter, and because of my change, the objects from the adapter where stale. That's where my logic went wrong. It's not that the new query was stale, but I didn't clear the adapter. So doing this before fixed it:

      beacons.clear();
      userBeaconAdapter.clearItems();