Property accessor 'xxxx' on object 'xxxx' threw the following exception:'It is not allowed to read or to write an instance marked for deletion.'

8 posts, 0 answers
  1. Robert
    Robert avatar
    21 posts
    Member since:
    Feb 2009

    Posted 09 Sep 2010 Link to this post

    Hello,

    I'm using a per request scope, I have a treeview bound to hierarchical list of categories, which uses OpenAccessDataSource. When I delete category and bind both treeview and datasource, I get the error above.

    Why the datasource takes deleted object into account? How can I avoid the problem?

    I tried to commit transaction and the begin new one after 'delete', but then I get NoSuchObjectException.

    Thanks for answer,
    Robert
  2. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 10 Sep 2010 Link to this post

    Hi Robert,

    Without knowing how your class model (of categories) is structured.
    Does your category (the one you delete) have a reference to a list of sub categories or a parent category?

    Obviously "something" is referring (either in collection or as a single reference) to the category you deleted. That's also why you see the "object not exist" error after a commit.

    Regards

    Henrik
  3. DevCraft banner
  4. Robert
    Robert avatar
    21 posts
    Member since:
    Feb 2009

    Posted 10 Sep 2010 Link to this post

    Hi Henrik,

    thank you for the answer.

    the category class looks like this:

        public partial class TCategory
        {
            //The 'no-args' constructor required by OpenAccess.
            public TCategory()
            {
            }
     
            [Telerik.OpenAccess.FieldAlias("iDtCategory")]
            public int IDtCategory
            {
                get { return iDtCategory; }
                set { this.iDtCategory = value; }
            }
     
            [Telerik.OpenAccess.FieldAlias("createTime")]
            public DateTime? CreateTime
            {
                get { return createTime; }
                set { this.createTime = value; }
            }
     
            [Telerik.OpenAccess.FieldAlias("description")]
            public string Description
            {
                get { return description; }
                set { this.description = value; }
            }
     
            [Telerik.OpenAccess.FieldAlias("disabled")]
            public bool Disabled
            {
                get { return disabled; }
                set { this.disabled = value; }
            }
     
            [Telerik.OpenAccess.FieldAlias("iDtCategoryParent")]
            public int? IDtCategoryParent
            {
                get { return iDtCategoryParent; }
                set { this.iDtCategoryParent = value; }
            }
     
            [Telerik.OpenAccess.FieldAlias("imageUrl")]
            public string ImageUrl
            {
                get { return imageUrl; }
                set { this.imageUrl = value; }
            }
     
            [Telerik.OpenAccess.FieldAlias("name")]
            public string Name
            {
                get { return name; }
                set { this.name = value; }
            }
     
            [Telerik.OpenAccess.FieldAlias("ordinalAtLevel")]
            public int OrdinalAtLevel
            {
                get { return ordinalAtLevel; }
                set { this.ordinalAtLevel = value; }
            }
     
            [Telerik.OpenAccess.FieldAlias("tCategory1")]
            public TCategory TCategory1
            {
                get { return tCategory1; }
                set { this.tCategory1 = value; }
            }
     
            [Telerik.OpenAccess.FieldAlias("categories")]
            public IList<TCategory> Categories
            {
                get { return categories; }
            }
     
     
        }
     
    [Telerik.OpenAccess.Persistent(IdentityField="iDtCategory")]
        public partial class TCategory
        {
            private int iDtCategory; // pk
     
            private DateTime? createTime;
     
            private string description;
     
            private bool disabled;
     
            private int? iDtCategoryParent;
     
            private string imageUrl;
     
            private string name;
     
            private int ordinalAtLevel;
     
            private TCategory tCategory1; // inverse TCategory.categories
     
            private IList<TCategory> categories = new List<TCategory>();  // inverse TCategory.tCategory1
        }


    and the datasource:

    <telerik:OpenAccessDataSource ID="dataCategories" runat="server" EnableDelete="True"
                            EnableInsert="True" EnableUpdate="True" ObjectContextProvider="DataManager.ObjectScopeProvider1, DataManager"
                            OrderBy="" TypeName="DataClasses.TCategory" Where="tCategory1 == @tCategory1"           OnContextCreating="data_ContextCreating" OnContextDisposing="data_ContextDisposing">
                            <WhereParameters>
                                <asp:Parameter Name="tCategory1" />
                            </WhereParameters>
                </telerik:OpenAccessDataSource>



    so that the category has reference to parent category as well as a list of child categories. But I don't understand why the datasource doesn't refresh it's collection?

    Thanks,
    Robert

  5. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 10 Sep 2010 Link to this post

    Hi Robert,

    Thanks for elaborating.

    The category that you delete is it by chance a category that has sub categories? And how is sub categories mapped (is it a 1:m with a join table or with an inverse field)?
    Depending on whether the category.SubCategories is defined as "managed" or having other kind of "cascading delete" options for items in that collection either OpenAccess will handle it or will have to remove the items in the sub category collection yourself (when deleting a category, which has subcategories)

    Check out the [Depend] attribute in the docs or cascading deletes... I guess what you want to do is actually to delete the sub categories of a category when the category itself is deleted, right?

    Often this is done in the class with the Depend attribute, like (pseudo code):

    public class Category
    {
       private Category parent;
       [OpenAccess.Depend]
       private IList<Category> subCategories;
    }

    Decorating the field holding the list with Depend attribute, tells the OA runtime to delete items in this list too when the object itself (here Category instance) is deleted.

    Regards

    Henrik
  6. Robert
    Robert avatar
    21 posts
    Member since:
    Feb 2009

    Posted 10 Sep 2010 Link to this post

    Hi Henrik,

    the category I'm trying to delete has no subcategories, it has only parent category. As you can see in class definition I'm not using depend attribute and I'm not trying to use cascading delete, I want just delete this one particular category which has no children.

    The error is raised in property getter of Category.Name which is set in RadTreeView as DataTextField and during RadTreeView.DataBind().

    I have to also mention that the whole scenario is under ajax using RadAjaxManager. 

    I think openaccess datasource still holds deleted category in collection and when tree view wants to get the name for that particular node, this error is thrown. But I don't understand why openaccess datasource doesn't refresh itself.

    Best reagrds,
    Robert
  7. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 10 Sep 2010 Link to this post

    Hi Robert,

    Thanks for elaborating.

    I think you're right, it stills holds the reference to the deleted object, thus you will get the error.

    Calling DataBind on the control in question really should be enough, since it will execute the select statement again (hopefully). Did you try to unbind the control (DataSource = null) and rebind it again (DataSource = oaDatasource) ?

    Regards

    Henrik
  8. Robert
    Robert avatar
    21 posts
    Member since:
    Feb 2009

    Posted 10 Sep 2010 Link to this post

    Hi Henrik,

    thanks once again for answer.

    I finally realized what is the problem. I called scope.Remove() but didn't commit the transaction. The transaction was commited only at the end of request, however TreeView.DataBind was called prior to transaction commit. So I tried Transaction.Flush and it works now.

    This is I think common case when someone deletes something using ajax and during the same request rebinds respective control after the delete.

    I'm going to turn on l2 cache to see what happens then:)

    Thanks!
    Robert
  9. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 10 Sep 2010 Link to this post

    Hi Robert,

    Thanks for sharing and it is crystal clear to me what the problem (and the solution) is now.

    I don't think you will have any problems regarding the L2 cache (other than optimized performance - not really a problem is it :-)).

    /Henrik
Back to Top
DevCraft banner