Tuesday, August 18, 2015

The object has been updated by another user since it was last fetched.

Sometimes when we are updating Content Types programmatically, we might come across the following exception:
“The object has been updated by another user since it was last fetched”
I got this exception for the following code in my Feature Receiver’s FeatureActivated method:
private SPContentType EnsureContentType(SPWeb web, string contentTypeName)
{
    SPContentType contentType = web.ContentTypes[contentTypeName];
    if (contentType == null)
    {
        SPContentType parentContentType = web.ContentTypes[SPBuiltInContentTypeId.Item];
        contentType = new SPContentType(parentContentType, web.ContentTypes, contentTypeName);
        contentType = web.ContentTypes.Add(contentType);
    }

    contentType.FieldLinks[SPBuiltInFieldId.Title].Hidden = true;
    contentType.Description = contentTypeName;
    contentType.Group = "Test";
    contentType.Update();
}

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    SPSite site = properties.Feature.Parent as SPSite;
    using (SPWeb web = site.OpenWeb())
    {
        SPContentType contentType = EnsureContentType(web, "My Content Type");
        Guid guid = "CBE1FD3E-351B-43B8-94A6-33868300FA6E"; //Some valid Guid
        if (contentType.FieldLinks[guid] != null)
        {
            contentType.FieldLinks.Delete(guid);
            contentType.Update(true); //This is the line that throws exception
        }
    }
}
This exception occurs randomly. The same piece of code is working fine in a different place. The only way that I found to fix this problem is to instantiate new SPSite and SPWeb objects, instead of using SPContext.Current.Web or SPWeb from properties object.
So, I changed my code as shown below to get rid of the exception.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    SPSite site = properties.Feature.Parent as SPSite;
    using (SPWeb web = site.OpenWeb())
    {
        SPContentType contentType = EnsureContentType(web, "My Content Type");
        Guid guid = "CBE1FD3E-351B-43B8-94A6-33868300FA6E"; //Some valid Guid
        //Instantiating new SPSite and SPWeb objects
        using (SPSite newSite = new SPSite(web.Site.ID))
        {
            using (SPWeb newWeb = newSite.OpenWeb(web.ID))
            {
                contentType = newWeb.ContentTypes[contentType.Id];
                if (contentType.FieldLinks[guid] != null)
                {
                    contentType.FieldLinks.Delete(guid);
                    contentType.Update(true); //No more exceptions
                }
            }
        }
    }
}
Note: You might also face this problem if you are creating/updating Content Types using xml files. There is a Version attribute in your Elements.xml file that needs to be removed to fix the same problem. For more information, you can refer to this blogwhere the problem is explained in detail.
That’s it guys……a small post on a problem that can be a huge pain.

No comments:

Post a Comment