toshiomagic
toshiomagic

Reputation: 1659

Entity with id already exists and does not exist simultaneously in CosmosDB

I'm banging my head against the wall on this one.

I've got a function that is basically an Upsert called TryCreateOrUpdate. I do realize that an upsert function now exists, but this is some older code. Here's the function:

public static async Task<string> TryCreateOrUpdate<T>(T data) where T : ViewModelBase
{
    var options = string.IsNullOrWhiteSpace(data.PartitionKey) ? null : new RequestOptions { PartitionKey = new PartitionKey(data.PartitionKey) };
    try
    {
        var response = await Client.CreateDocumentAsync(Collection.SelfLink, data, options, true);
    }
    catch (DocumentClientException dce)
    {
        switch (dce.StatusCode.Value)
        {
            ...
            case HttpStatusCode.Conflict:
                try
                {
                    var link = UriFactory.CreateDocumentUri(_databaseId, _collectionId, data.Id);
                    await Client.ReplaceDocumentAsync(link, item, options);
                }
                catch (Exception e)
                {
                    return $"There was an error updating the document.";
                }
                break;
            default:
                ...
        }
    }
    catch (Exception e)
    {
        return "There was an unknown error creating the document.";
    }
    return "OK";
}

I'm trying to insert a document with an id that is 6 digits as a string.

I checked my Cosmos DB and I can confirm that there is no document in the database with the id which I am trying to upsert. So it should result in a create.

The line that creates the document throws a DocumentClientException:

Entity with the specified id already exists in the system.

However, the replace line of code throws this exception:

Entity with the specified id does not exist in the system.

Um, what? Does it exist or not?!

As I said, I check before I run this and the document doesn't exist.

I even tried changing all this code to use the newer UpsertDocumentAsync and I still get the error

Entity with id already exists in the system

even though, as I've said, the document DOES NOT EXIST.

Upvotes: 5

Views: 8663

Answers (2)

Jean-Paul Smit
Jean-Paul Smit

Reputation: 338

I ran into the exact same error when trying to create a document. Although the ID of the document was unique, it slipped through my mind that I configured a unique key on the container. As it is (almost?) impossible to find the unique keys defined on a container in Cosmos Db using the Azure portal, this can easily be overlooked.

Upvotes: 2

toshiomagic
toshiomagic

Reputation: 1659

While I do not quite understand the inner workings of the CosmosDb and related packages as it relates to this issue, it seems that the cause is a rewrite of how the Id field in a base class is written.

It used to be written this way:

public string id => Id;

public string Id { get; set; }

And then it got changed to:

[JsonProperty("id")]
public string Id { get; set; }

Note that the id => Id has been removed. And now it's causing issues. We changed it to:

public string id {
    get { return Id; }
    set { Id = value; }
}

public string Id { get; set; }

and now everything works like it used to.

Upvotes: 4

Related Questions