Realm-java: java.lang.IllegalStateException: Changing Realm data can only be done from inside a transaction.

Created on 5 Oct 2015  ·  23Comments  ·  Source: realm/realm-java

10-05 03:44:32.511    1402-1402/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.test.materialup, PID: 1402
    java.lang.IllegalStateException: Changing Realm data can only be done from inside a transaction.
            at io.realm.internal.Table.throwImmutable(Table.java:1474)
            at io.realm.internal.Table.checkImmutable(Table.java:1074)
            at io.realm.internal.UncheckedRow.setString(UncheckedRow.java:207)
            at io.realm.PostRealmProxy.setBody(PostRealmProxy.java:92)
            at com.test.materialup.ui.PostActivity.onClick(PostActivity.java:107)
            at com.test.materialup.adapter.PostRecyclerAdapter$PostViewHolder$1.onClick(PostRecyclerAdapter.java:71)
            at android.view.View.performClick(View.java:4438)
            at android.view.View$PerformClick.run(View.java:18422)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
            at dalvik.system.NativeStart.main(Native Method)

While changing a Post object value it gets crashing

 @Override
    public void onClick(int position) {
        Post post = postRecyclerAdapter.getPost(position);
        post.setBody("Hello Wolrd");
    }
T-Help

Most helpful comment

@mubarak1361 How about adding beginTransaction() before post.setBody("Hello Wolrd")? Do you still get IllegalStateException?

All 23 comments

A stacktrace is not the best way to issue a bug. Please take a look at https://github.com/realm/realm-java#getting-help

That being said it looks like you are trying to modify a Realm object outside of a transaction, which is not allowed.

@emanuelez ya, am changing a realm object to update the adapter items.then how to fix this issue?

@mubarak1361 How about adding beginTransaction() before post.setBody("Hello Wolrd")? Do you still get IllegalStateException?

@dalinaum ya, got it thank you :)

@mubarak1361 Invoking commitTransaction() after modifying a Realm object might be needed too.

Did you solve your problem well, @mubarak1361 ?

@dalinaum issue solved

Great. Please feel free to reopen if you encouter futher problems with this.

Thanks. So helped.

This has become an issue with the Android's two way data binding. If I can't change the model directly I might as well ditch the way binding, or create a temp model to store data and then push it with commit to realm. Any workarounds with this?

You need to write Realm data inside an transaction, no way around that to ensure ACID.
What you can do is using copyFromRealm to copy the object to memory, attach it to two-way databinding and then do copyToRealm when done.

Is it smart to open a transaction sometimes on the start of my activity's lifecycle like onCreate/onResume and simply close it on onPause/onDestroy? This way I can use the same model and use the full benefits of two way binding.

It would work yes, but transactions are blocking across all threads. So if you have a background thread doing a write when you start you suddenly ANR'ed your app.

Good to know. Thanks

@MenilV I'd opt against two-way databinding because synchronous writes on the UI thread can be blocking, but one-way databinding isn't that difficult

@MenilV you might wanna check out this

realm-1-2-0-android-data-binding

@sirvon yeah, actually an Observable is probably the way to go here. Didn't think of it right away.
btw @Zhuinden this article is great.

for every change of data from a object instance of a RealmObject class, for example in your case :
post.setBody("Hello Wolrd");
the Realm requires you to do it within a transaction, then use :
realm.beginTransaction();
post.setBody("Hello Wolrd");
realm.closeTransaction();
this will work.

@cmelchior I get this error when I edit a object retrieved from Realm outside of a transaction.

Currently in my system, for a given activity we do three things involving realm.

1) everytime we make a service call for a list of Object, List we persist the list received in realm from a function-scope-lived realm instance in our data manager
2) When a service call fails we grab a list of Cats from another function-scope-lived realm instance in our data manager
3) When we press a button in the activity we temporarily change the color of a cat (this is what throws the error if we are using a Realm persisted list of cats in the case of 2).

I would like to freely allow any sequence of 1) 2) 3) but in a safe way. How can I do that. Do I just keep one realm instance in my data manager class and then update to that one so that I don't ANR the app?

I get this error when I edit a object retrieved from Realm outside of a transaction.

well yes, you can only modify a RealmObject inside a transaction

we temporarily change the color of a cat

from the perspective of Realm, there is no "temporarily" - you modify the object, it will have that property, such change can only be transactional and you must commit said transaction in order for the change to take place

@Zhuinden that makes sense! thank you. But what about safely intermingling 1) 2) and 2) without conflict between the realm instances?

will a opening of a asynchronous java realm transaction block all other realm instance transactions / insertions?

Yes, there can only be 1 transaction open at a time to a given Realm file, on any thread and in any process

Other beginTransaction() calls get blocked for that time

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CNyezi picture CNyezi  ·  3Comments

harshvishu picture harshvishu  ·  3Comments

Merlin1993 picture Merlin1993  ·  3Comments

yuwu picture yuwu  ·  3Comments

Frasprite picture Frasprite  ·  3Comments