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");
}
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
@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
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
Most helpful comment
@mubarak1361 How about adding
beginTransaction()beforepost.setBody("Hello Wolrd")? Do you still get IllegalStateException?