Removing object from realm based on Id works but throws error

This is my model:

public class Amestec : RealmObject
{
    [PrimaryKey]
    [MapTo("_id")]
    public ObjectId Id { get; set; } = ObjectId.GenerateNewId();
}

I’m trying to remove an Amestec using:

 public static void RemoveAmestecFromDB(ObjectId id)
    {
        var realm = Realm.GetInstance(_syncConfiguration);

        var selectedAmestec = realm.All<Amestec>().FirstOrDefault(c => c.Id == id);
        if(selectedAmestec == null)
            return;
        using (var transaction = realm.BeginWrite()) {
            realm.Remove(selectedAmestec);
            transaction.Commit();
        }
}

or

 public static void RemoveAmestecFromDB(ObjectId id)
    { 
        var amestec = _realm.Find<Amestec>(id);
        _realm.Write(() => {
            _realm.Remove(amestec);
        });
    }

The object gets removed but I get the following error:

RealmInvalidObjectException: Attempted to access detached row
Realms.NativeException.ThrowIfNecessary (System.Func`2[T,TResult] overrider) (at <599fd848fd9040f0a59e4106e4838256>:0)
Realms.ObjectHandle.GetValue (System.String propertyName, Realms.RealmObjectBase+Metadata metadata, Realms.Realm realm) (at <599fd848fd9040f0a59e4106e4838256>:0)
Realms.RealmObjectBase.GetValue (System.String propertyName) (at <599fd848fd9040f0a59e4106e4838256>:0)
Amestec.get_Id () (at Assets/Scripts/Model/AmestecModel.cs:10)
...

Can you post the entire stacktrace? It looks like something is trying to access the Id of the just-removed object. This can be for example if you have wired up object change notifications and are not correctly filtering-out deletions.

Heya, I don’t think I have anything like object change notifications but here is the stacktrace:

RealmInvalidObjectException: Attempted to access detached row
Realms.NativeException.ThrowIfNecessary (System.Func`2[T,TResult] overrider) (at <599fd848fd9040f0a59e4106e4838256>:0)
Realms.ObjectHandle.GetValue (System.String propertyName, Realms.RealmObjectBase+Metadata metadata, Realms.Realm realm) (at <599fd848fd9040f0a59e4106e4838256>:0)
Realms.RealmObjectBase.GetValue (System.String propertyName) (at <599fd848fd9040f0a59e4106e4838256>:0)
Amestec.get_Id () (at Assets/Scripts/Model/AmestecModel.cs:10)
DeleteAmestecOnClick.DeleteCurrentAmestec () (at Assets/Scripts/Utility/OnClick/Amestec/DeleteAmestecOnClick.cs:27)
UnityEngine.Events.InvokableCall.Invoke () (at <07c89f7520694139991332d3cf930d48>:0)
UnityEngine.Events.UnityEvent.Invoke () (at <07c89f7520694139991332d3cf930d48>:0)
UnityEngine.UI.Button.Press () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:68)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:110)
UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:50)
UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:262)
UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:385)

Could you show the code of DeleteCurrentAmestec?

I don’t think I have anything like object change notifications

If you have used any method from this page that concerns Amestec, we’d like to see that/those.

More specifically, it looks like in DeleteAmestecOnClick.cs:27 you’re accessing Amestec.Id after the object has been deleted.

1 Like

Hm, I’m passing the ID to the RemoveAmestecFromDB witch is above, but this should happen before deletion right?

private void DeleteCurrentAmestec()
    {
        var amestecController = AmestecController.Instance;
        var currentAmestec = amestecController.CurrentAmestec;
        if (currentAmestec != null) {
            RealmController.RemoveAmestecFromDB(currentAmestec.Id);
            amestecController.RefreshNamesView();
            amestecController.GetAmestecViewDataInstance().ResetFieldsNull();
            amestecController.ClearIstoricView();
            amestecController.SetActiveBtns(false);
            amestecController.GetSliderInstance().GetComponent<AmestecViewSlider>().RefreshSliderView();
        }
    } 

sorry, line 27 is RealmController.RemoveAmestecFromDB(currentAmestec.Id)

I have fixed it by giving amestecController.CurrentAmestec = null right after RemoveAmestecFromDB … I don’t understand exactly what was going on but thank you guys a lot for the help!

I don’t understand exactly what was going on

That feels like something was reacting to the deletion and trying to access fields of the deleted object (Amestec.Id as Nikola said). What puzzles me is that it seems that part of the “reaction” is to call the delete method again. You may want to investigate this.
Anyway, I assume that amestecController.CurrentAmestec is basically caching a RealmObject. If so, by not setting it manually to null when an object is deleted, any subsequent reference to amestecController.CurrentAmestec throws as you see. In fact, when you set it to null, the next call to DeleteCurrentAmestec won’t throw because you have the following check if (currentAmestec != null) {

If my assumptions are correct this should help you to have a better overview of what’s going on.

1 Like

Yeah it’s just a reference to a realm object, I thought it was something like calling the function again but I can’t figure out why this was happening, I might have to double check if it’s calling the function onmousedown or taking multiple inputs, if not I have no idea