This is a migrated thread and some comments may be shown as answers.

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

7 Answers 617 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Robert
Top achievements
Rank 2
Robert asked on 09 Sep 2010, 01:08 PM
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

7 Answers, 1 is accepted

Sort by
0
IT-Als
Top achievements
Rank 1
answered on 10 Sep 2010, 11:56 AM
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
0
Robert
Top achievements
Rank 2
answered on 10 Sep 2010, 01:04 PM
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

0
IT-Als
Top achievements
Rank 1
answered on 10 Sep 2010, 01:17 PM
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
0
Robert
Top achievements
Rank 2
answered on 10 Sep 2010, 01:50 PM
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
0
IT-Als
Top achievements
Rank 1
answered on 10 Sep 2010, 01:59 PM
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
0
Robert
Top achievements
Rank 2
answered on 10 Sep 2010, 02:22 PM
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
0
IT-Als
Top achievements
Rank 1
answered on 10 Sep 2010, 02:26 PM
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
Tags
General Discussions
Asked by
Robert
Top achievements
Rank 2
Answers by
IT-Als
Top achievements
Rank 1
Robert
Top achievements
Rank 2
Share this question
or