Realm-java: native crash in RealmResults#deleteAllFromRealm()

Created on 10 May 2016  ·  18Comments  ·  Source: realm/realm-java

Goal

allow to call RealmResults.deleteAllFromRealm() against the RealmResults object which contains deleted object in it.

Expected Results

no native crash and all existing objects are deleted.

Actual Results

native crash

Steps & Code to Reproduce

executing following sample code

Code Sample

        realm.beginTransaction();
        realm.createObject(Dog.class);
        realm.createObject(Dog.class);
        realm.commitTransaction();

        RealmResults<Dog> results = realm.where(Dog.class).findAll();

        realm.beginTransaction();

        Dog dog = results.get(0);
        dog.deleteFromRealm();

        results.deleteAllFromRealm();

        realm.commitTransaction();

Version of Realm and tooling

Realm version(s): current master

Android Studio version: 2.1

Which Android version and device: 4.1.1 on genymotion

Blocked T-Bug-Crash

Most helpful comment

I don't think we should call sync_if_needed since it may cause unintentional deletes of objects that are not included in the results on current version, but included in the results on latest version.

All 18 comments

i doubt we need call sync_if_needed in deleteAllFromRealm()

I don't think we should call sync_if_needed since it may cause unintentional deletes of objects that are not included in the results on current version, but included in the results on latest version.

@zaki50 Is there core issue created for this?

@cmelchior not yet

Wait, isn't this because you're deleting invalid objects through deleteAllFromRealm()?

@zaki50 Have you been able to write a core unit test which reproduces it?

@zaki50 For these kind of issues the best is to create a PR with a unit tests that fails.

It seems that sync_if_needed() isn't called.

@kneth As I asked, isn't it because the RealmResults is a TableView that is desynchronized due to not calling syncIfNeeded() and no longer being "live" even in a transaction, and therefore having invalid objects in the RealmResult and the native pointer being wrong due to being a previous version of the Table itself?

Even in Realm Transactions, the results are no longer live since 0.89.0.
This would probably work fine on a RealmList, but not on a RealmResult, because the version of the RealmResult is mismatched.

Now I truly do wonder if size() works on a RealmResults in a transaction after a delete.

We have uncovered a bug in the underlying database and are working on a fix: https://github.com/realm/realm-core/issues/827

@cmelchior oh. Cool! Sorry about rambling then.

@bmunkholm sure. I'll do in next time.

Any short term workarounds? Is there an older version which doesn't exhibit this behavior? We just spotted this bug and it's holding up a release.

It only effect you if you first delete one item indirectly, then delete all of them. If that is happening it sounds like some application logic could be rewritten instead? That said anything before 0.89 should not suffer from this.

One other work-around is avoiding deleting items indirectly. E.g. Doing list.get(0).deleteFromRealm() should be replaced with list.deleteFromRealm(0).

@colintheshots Current workaround is iterating results and call deleteFromRealm() to each valid(obj.isValid() == true) object.

@Zhuinden

Now I truly do wonder if size() works on a RealmResults in a transaction after a delete.

size() returns the same value but i think it is the design.

It is supposed to use results.get(0).isValid() to check in such case.

The Realm Core update merged in #2803 fixes this issue. I have added a test which is identical to the code snippet mentioned when the issue was opened.

Was this page helpful?
0 / 5 - 0 ratings