Closed CrimsonKyle closed 8 years ago
I am using RestSharp by the way for the HTTP client
Hey @CrimsonKyle, standalone objects do not support RealmList
properties right now, but we're continuously working to improve and this functionality will be available soon.
In the mean time, you can workaround this issue by using JsonConvert.PopulateObject
:
realm.Write(() => {
var parent = realm.Create<Parent>();
JsonConvert.PopulateObject(response.Content, parent);
});
This was a game changer!
Any word on when this might be supported? I'm having to rewrite large chunks of my code because of this issue.
This was actually solved in the recently released version 0.77.0, but we unlisted it because there was a bug in the weaver code. We are fixing it and will have a patched release ready very soon.
@kristiandupont Oh man, yeah I made an issue about that. But it was a duplicate. Well I guess I can exercise a little patience here. Looking forward to the release!
@kristiandupont Hi Kristian sorry to bother you, I've just downloaded the latest version of Realm 0.77.1. When I deserialize the object like so:
var object = JsonConvert.DeserializeObject<T> (response.Content);
The RealmList isn't populated with the list (array) data. Am I doing something wrong here?
public class ReportChart : RealmObject
{
public string Title { get; set; }
public string Url { get; set; }
}
public class Report : RealmObject
{
...
public RealmList<ReportChart> EntryCharts { get; }
}
No calls have been made to db.Manage() at this stage. The object is still standalone.
Hi @UKDeveloper99, try replacing your declaration from RealmList<ReportChart>
with IList<ReportChart>
-- that way, a realm object can be created as standalone even with a list. When you then Realm.Manage()
it in a transaction, it will all be persisted properly.
It's working hallelujah!!!!!!!!!!
@kristiandupont Sorry it's me again I'll stop bothering you soon I promise. Since updating I keep getting a load of these exceptions throughout my code.
Realms.RealmInvalidObjectException has been thrown Attempted to access detached row.
You'll probably have a much better idea of what throws this exception than I will.
Bit more info: This is when I'm using the objects after they're persisted in the database. I've made sure to call .ToList() on all the lists etc. So it's not operating on the live list.
It's alright, no bother at all :-)
This error means that you are trying to read or write a property on an object that is no longer attached to a Realm. This could either be because it has been deleted from the Realm, or it could be because the Realm was closed. If none of those apply, it must be some other bug, potentially in our code so please let me know if this seems to be the case.
I'll look in to it and get back to you.
@kristiandupont Hi Kristian, starting to bang my head against the wall with this one. Feeling under pressure, this project was ready to be shipped and is now delayed (we are supposed to release today). This Realm issue I'm having is breaking everything. It's only been introduced since v0.77.1. It was working fine in 0.76.1.
I don't want to revert to 0.76.1, I'm a big advocate for Realm I like it a lot, I'll be honest there's some mixed feelings about it in the office. Long story short, if I revert to Realm 0.76.1 it will require a modification on the back end to change back to the old way of passing data which is related to the problem we were having above. Passing a List of objects in the Report object from the api. So the guys in the office will know the new version is broken again and they'll likely want to steer away from it for good.
So moving on, to describe this issue I'm having I'll do my best to explain the setup as I really don't have the time constraints to put together a test project for the issue. If we can fix this with your knowledge of Realm then that would be a bonus.
So there are 2 versions of the project both of which I'm having the same issue. a Xamarin.IOS project with a core PCL sub project. And a Xamarin.Android project with a core PCL sub project. They both use the same core. It's all built on MvvmCross with data bindings. So here is how the data comes in specifically in regards to the Realm parts.
return Reports.ToList();
I don't want to revert to 0.76.1, I'm a big advocate for Realm I like it a lot, I'll be honest there's some mixed feelings about it in the office. Long story short, if I revert to Realm 0.76.1 it will require a modification on the back end to change back to the old way of passing data which is related to the problem we were having above. Passing a List of objects in the Report object from the api. So the guys in the office will know the new version is broken again and they'll likely want to steer away from it for good.
So moving on, to describe this issue I'm having I'll do my best to explain the setup as I really don't have the time constraints to put together a test project for the issue. If we can fix this with your knowledge of Realm then that would be a bonus.
So there are 2 versions of the project both of which I'm having the same issue. a Xamarin.IOS project with a core PCL sub project. And a Xamarin.Android project with a core PCL sub project. They both use the same core. It's all built on MvvmCross with data bindings. So here is how the data comes in specifically in regards to the Realm parts.
return Reports.ToList();
this.DelayBind(() =>
{
var set = this.CreateBindingSet<ReportItemView, Report>();
set.Bind(LabelTitle).To("TradeType + ' ' + Title");
set.Bind(LabelDate).To(vm => vm.RelevanceDate).WithConversion("DateLocalization");
set.Bind(LabelStatus).To(vm => vm.Status);
set.Bind(LabelStatus).For(l => l.TextColor).To(vm => vm.Status).WithConversion("StatusLabelColor");
set.Bind(_imageCellViewLoader).To(vm => vm.TradeType).WithConversion("ResourceImage");
set.Apply();
});
Each bind function binds the text value of a label (or something else) to properties in the view model. In this case the Reports list data is bound to table source. Then the above code is the bindings for each cell in the table. This is inside a class that is used by DequeueReuseableCell an iOS function. This used to work fine before the update. But now as soon as it reaches this point it's getting the Realms.RealmInvalidObjectException has been thrown Attempted to access detached row.
As far as I'm aware there shouldn't be an issue here, I'm attempted to access the persisted realm data via data bindings from the view model. Off the top of my head is there a way I can create a list that is read only and no longer affected by the realm, I only want to use it for the displaying of data. Because it seems like somewhere along the line Realm thinks the data I have isn't associated with a realm. I don't have a single call to Realm.Close in my entire project.
I think I've narrowed the problem down to just the binding of TableView cells. So somehow it's using data for the cell that is not attached to a Realm. As far as realm is concerned. It probably wasn't catching that in previous versions because I imagine that exception code is new in this version.
Hi @UKDeveloper99,
I will try and see if I can replicate your bug somehow but I suspect it might be a bit hard. I am sorry about this situation -- I hope we can resolve it. Are you sure that
1) the realm you are binding to is still open (i.e. not scoped in a using
statement etc), and
2) the items being bound are not deleted, say, on another thread?
Thanks @kristiandupont
I imagine you can replicate it quite easily, just create an iOS project with a PCL. Persist some objects in the PCL (Add a view model with a list container property of those objects). Bind the list to a table view source. Bind the object properties inside the table cell class. I'll try and put together a test project this evening if I haven't fixed it by then.
Will look in to your other comments now.
@kristiandupont Here's some code.
public static readonly string Key = "ProductItemView";
private readonly MvxImageViewLoader _imageViewLoader;
public ProductItemView(IntPtr handle) : base(handle)
{
_imageViewLoader = new MvxImageViewLoader(() => this.ImageProductLogo);
this.DelayBind(() =>
{
// Debug realm code
var db = Realms.Realm.GetInstance(Settings.RealmFile);
var products = db.All<Product>().ToList();
var set = this.CreateBindingSet<ProductItemView, Product>();
set.Bind(LabelName).To(vm => vm.Title);
set.Bind(_imageViewLoader).For(imageLoader => imageLoader.ImageUrl).To(vm => vm.Icon);
set.Apply();
});
}
I've put this debug Realm code right before the binding happens. (Products are essentially the same as reports in regards to the way they are bound to a table source/cell). This code gives me a list of 4 Products (which is correct). Realm reports them all as managed (true). So it's more likely the way the binding happens for table cells that is breaking something than Realm itself.
@kristiandupont I'm creating a test project.
@UKDeveloper99 Looking at your code, DelayBind
stood out to me. Are you using MVVMCross?
Or is DelayBind
your own method?
@AndyDentFree I'm using MvvmCross yes correct.
I've made the test project but can't seem to reproduce the problem. I shall endeavor further. Here it is just incase you guys want to take a look. https://www.dropbox.com/s/61zohanjz9sg3c7/Sandbox.zip?dl=0
I've been seeing similar issues with 0.77.1 and databinding. We're not using MvvmCross, and the same code works fine with 0.76.1. I'll see if I can pull mine out into a reproducible test project.
Well, I don't seem to be able to reproduce the issue in a test project either. The real app has a rather complex navigation structure that I did not port over, and I suspect that might be part of the issue.
Exactly the same as you. I'm only getting the error consistently in one part of my app. So trying to narrow down what's causing the issue.
I'm just sorta throwing out a guess here, but I highly suspect that prior to 0.77.1 A lot of people's projects were littered with this detached row accessing but because there was no handling for it they didn't know about it. Now that exception check is in place it's popping up everywhere.
Realms.RealmInvalidObjectException: Attempted to access detached row
at Realms.NativeException.ThrowIfNecessary () [0x00013] in
Just can't get rid of it and no idea how to create it either.
@UKDeveloper99 Try this: add an additional property to your realm object, like this:
public string Debug
{
get
{
Console.WriteLine(this.Realm.IsClosed);
return "";
}
set
{
Console.WriteLine(this.Realm.IsClosed);
}
}
Databind something to this property and see what is printed. Unbind the other properties so it stops crashing. Now, if at any point in time your console says true
, we know that the problem is that the realm has been closed. If not, it must have been deleted somewhere. That will at least get us a bit further.
I modified it to this
public string DebugProp
{
get
{
Debug.WriteLine(Realm.GetInstance(Settings.RealmFile).IsClosed);
return "";
}
set
{
Debug.WriteLine(Realm.GetInstance(Settings.RealmFile).IsClosed);
}
}
I'm not able to get access this.Realm from the realm object.
I got false for every bound report.
I'm not able to get access this.Realm from the realm object.
You should be, it's in the RealmObject
class, which should be your base class? Calling GetInstance()
is not the same as this will create a new realm if it was closed (albeit to the same file).
My object inherits from RealmObject but there is no property to access the Realm for the object. Only methods such as IsManaged etc. this.Realm is undefined.
You could confirm this by trying it yourself in the test project I sent.
The only visible properties in the parent class RealmObject are IsVisible and IsValid
Ah right, it's internal, sorry! Try to set a breakpoint and inspect it with the debugger instead.
One moment
In the locals inspector the IsClosed property under Realm is false for every one.
It must be something to do with the way DequeueReusableCell works on iOS. And template selector on Android. I'm trying to think of workarounds for now.
The only thing I can think of is to copy the realm object to an intermediate object and bind to that instead.
You said that the only other way the exception is thrown is if the object has been deleted. Is there a way like above to determine if the object has been deleted.
If I step through the binding for every report, eventually I find one where every property has a yellow symbol. And says Realms.RealmInvalidObjectException: Attempted to access detached row. That must mean either some of the reports that are managed are corrupted somehow or it's related to this dequeue reusable cell.
The if you are running on the iOS simulator, you can keep the database open simultaneously in the Realm Browser. You can find the file as shown here: http://stackoverflow.com/a/28465803/1417293
I am running into the exact same situation that is occurring above and I googled for like 3 hours until I realized you all were talking about it under "my issue"... anyways I am trying to pass a list of deeply nested realm objects between pages and it is immediately throwing detached row errors. (this was working correctly in 0.76.1) also my locals variables for my realm isClosed = false
So I am querying a List of a parent object with 4 levels of nested realm lists under them into a List of
Using IList not Realm List
Feels good I'm not the only one having that issue. It's also happening on my nested objects, so that may be the issue.
Do you guys have any Realm.Remove()
statements anywhere in your code? I don't know if it's feasible at all, but if you do, can you out-comment those and see if you get the same error? That should be the only other way an object can become detached.
Morning @kristiandupont, this is probably not what you want to hear, but I'm fairly certain there are no calls made to Realm.Remove in my code before the error occurs :(. I've already reverted to 0.76.1. Going to have to release the project like that.
I've created #746 for this issue, please move further discussion there.
I need Realm to Manage a JSON result that is deserialized into a RealmObject. What is the best way of doing this?
Error: System.Reflection.TargetInvocationException: "Exception has been thrown by the target of an invocation."
//*MODELS***//