No such object exception

8 posts, 1 answers
  1. Adrian
    Adrian  avatar
    15 posts
    Member since:
    Dec 2010

    Posted 13 Jun 2011 Link to this post

    I have 1 application (WindowsForms) and 1 same databse (concurency)

    First user delete sigle record, and second user modify same record, please give my a suggestion (or sample application)
    how to traking changes for modify and delete record, this problem occurs if we have
    a IList<Object> attached to the curent persistent object and another user delete
    a object from the IList.

    I attached a picture of this problem.
  2. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 16 Jun 2011 Link to this post

    Hi Negoa,

    Can I see the code where you delete the item in the list? And is the list (IList<PersistentType>) of objects managed? And how is the association mapped  (1:n with a join table or 1:n with a foreign key / reverse field)?

    It seems to me that the actual object in the list is deleted but the list still refers to it.
    When using managed 1:n OA will automatically update each side of the relation. However, when mapped as unmanaged 1:n (and especially 1:n with a join table) it is best practice to 1) Remove the item from the list 2) Delete the item itself.

    Regards

    Henrik
  3. DevCraft banner
  4. Adrian
    Adrian  avatar
    15 posts
    Member since:
    Dec 2010

    Posted 16 Jun 2011 Link to this post

    Hi Henrik

    I have the next code full runing from two computer in the same time :

    ModelContext Context = new Context();
    BindingList<PersistentObject> MyList = new BindingList<PersistentObject>();
      
    //etc.
      
    //In the Load of form
      
    private void FormLoad()
    {
        RefreshData();
    }
      
    private void RefreshData();
    {
        MyList = new BindingList<PersistentObject>(Context.PersistentObject.ToList();
      
        MyGrid.DataSource = MyList;
    }
      
    private void btnDelete_Click(object sender, EventArgs e)
    {
    try
    {
        PersistentObject ObjSelectedForDelete = MyGrid.CurrentRow.DataBoundItem as PeristentObject;
        Context.Delete(ObjectSelectedForDelete);
        Context.SaveChanges();
        RefreshData();
    }
    catch (telerik.OpenAccess.Exception.OptimisticVerification Except)
    {
         // Working fine if i have the next 3 row of code
        Context.ClearChanges();
        Context.Refresh(RefreshMode.OverwriteChangesFromStore);
        RefreshData();
    }
    }

    if you have another piece of code about this problem i shall  be very grateful
  5. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 16 Jun 2011 Link to this post

    Hello Neagoe,

    What is actually the behavior you want to achieve? If you just want to avoid the exception, you can try retrieving the object from the database right before calling Context.Delete(). This way you will know if the record still exists and whether you can delete it:
    PersistentObject ObjSelectedForDelete = MyGrid.CurrentRow.DataBoundItem as PeristentObject;
     
    PersistentObject originalObj = Context.PersistentObjects.FirstOrDefault(x => x.ID == ObjSelectedForDelete.ID);
    if(originalObj != null)
    {
        Context.Delete(ObjectSelectedForDelete);
        Context.SaveChanges();
    }
     
    RefreshData();

    If this is not what you are trying to achieve, please give us more details about what you want and expect to see in such cases, so we can help you further.

    Greetings,
    Alexander
    the Telerik team
    Want to use Telerik OpenAccess with SQL Azure? Download the trial version today. 
  6. Answer
    TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 16 Jun 2011 Link to this post

    Hi Neagoe (and Alexander)....

    I think the problem lies within how the object that is also a part of the list if removed delete... because:

    try
    {
        PersistentObject ObjSelectedForDelete = MyGrid.CurrentRow.DataBoundItem as PeristentObject;
        Context.Delete(ObjectSelectedForDelete);
        Context.SaveChanges();
        RefreshData();
    }

    The above code only deletes the object... However, depending on how this is mapped (see my other thread), you might need to remove it from the list too....  I usually use the pattern 1) Remove it from the list 2) Remove the object itself if it is an unmanaged 1:n which is the default now I guess.

    Update:
    So basically what needs to be added is:

    The "owner" object (say OwnerObject) of the list of persistent types... has a property with the list... say MyList...  So you need to do a OwnerObject.MyList.Remove(ObjectSelectedForDelete);  // Corresponding to step 1 above
    Context.Delete(ObjectSelectedForDelete); // Corresponding to step 2 above


    Regards

    Henrik
  7. Adrian
    Adrian  avatar
    15 posts
    Member since:
    Dec 2010

    Posted 16 Jun 2011 Link to this post

    Ok Henrik, you have a right all work fine now
    Another observation :
    But if a first user delete persistent object and second user modify same object how resolve you a optimistic verification exception
    at save.
     I have a invoice (at persistentobject)  with Partner, administration, product at attached list and second user delete selected the same partner for me, how you will treat this exception ?
  8. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 16 Jun 2011 Link to this post

    Hi Neagoe,

    Glad you got it working.

    Basically I divide exceptions of all kind into these categories:

    1) Exceptions that the application can recover from without user involvement
    2) Exceptions that the application can recover from with user involvement
    3) Exceptions that the application cannot recover from (BOOM - system down)

    One could argue that if you catch an optimistic concurrency exception you could use option 1) as:

    a) I need to refresh the object with the latest changes
    b) When merge in my changes and perform
    c) Try to Save (ie. Commit) again.

    However, the easiest way to do it is to let the user decide (option 2), like:

    a) Give the user an option to either 1) Discard his own changes (that is accept loss of data being edited) or 2) Overwrite the already committed changes to the database, thus..."Last man committing is the winner"

    OR

    b) Give up... Do nothing, just say: "Another user have changed the information you are currently editing. Refresh your information and try again".

    According to what kind of application it is and a bunch of other stuff... you can take a decision on what concurrency exception strategy you would prefer. There's really no easy answer here... exception the last option (b)..

    Regards

    Henrik
  9. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 17 Jun 2011 Link to this post

    Hi Neagoe,

    Oh by the way: If you found the answers useful, please mark the post as answered so that other forum visitors know about it.

    Regards

    Henrik
Back to Top
DevCraft banner