realm-java: Cannot modify managed objects outside of a write transaction

this is my code:

    @Override
    public <E extends RealmObject> void deleteAllAsync(Class<E> clazz, final RealmQuery query, final MHDDBCallBack callBack) {

        replacePropertyValue(query, "realm", null);

        RealmAsyncTask transaction = mRealm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {

                replacePropertyValue(query, "realm", realm);
                RealmResults<E> objects = query.findAll();

                for (E object : objects) {
                    object.deleteFromRealm();
                }
            }
        }, new Realm.Transaction.OnSuccess() {
            @Override
            public void onSuccess() {
                if (callBack != null) {
                    callBack.success();
                }
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(Throwable error) {
                if (callBack != null) {
                    callBack.failed(error);
                }
            }
        });

        transactions.add(transaction);
    }

    private void replacePropertyValue(Object object, String propertyName, Object newValue) {

        try {
            Field field = object.getClass().getDeclaredField(propertyName);
            field.setAccessible(true);
            field.set(object, newValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

It’ll crashed every time execute object.deleteFromRealm();. Someone said i should add realm.beginTransaction() before object.deleteFromRealm(), but not work for me . It’ll show another error The realm is already in a write transaction.

what should i do?

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 17 (8 by maintainers)

Most upvoted comments

@Zhuinden thanks, the problem has been solved. I add a new Interface param (DBCreateQuery) to throw a new query out instead of the RealmQuery param:

    public <E extends RealmObject> void deleteAllAsync(final Class<E> clazz,
                                                       final DBCreateQuery createQuery,
                                                       final DBCallBack callBack) {

        if (null != createQuery) {
            RealmAsyncTask transaction = mRealm.executeTransactionAsync(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                        RealmQuery query = realm.where(clazz);
                        createQuery.createQuery(query);
                        RealmResults<E> objects = query.findAll();
                        if (null != objects && objects.size() > 0) {
                            objects.deleteAllFromRealm();
                        }
                }
            }, new Realm.Transaction.OnSuccess() {
                @Override
                public void onSuccess() {
                    if (null != callBack) {
                        callBack.success();
                    }
                }
            }, new Realm.Transaction.OnError() {
                @Override
                public void onError(Throwable error) {
                    if (null != callBack) {
                        callBack.failed(error);
                    }
                }
            });

            transactions.add(transaction);
        }
    }

@archerLj you can delete RealmResults in executeTransactionAsync only if you query the RealmResults inside that transaction block, using the Realm instance that the transaction block gives you.