WindowsAzure-Toolkits/wa-toolkit-ios — Issue #31: Entity already exists error with inserting an entity into a Table
Author: desiltc
Created: 2012-02-04 09:43:21+00:00
State: open

I am running into a strange issue. When I try to do an insert, I get the following error back BUT the row does get inserted.

Error Domain=com.microsoft.WAToolkit Code=-1 "The specified entity already exists.
RequestId:c55fd56a-998d-4615-8eb1-ccfd3a10d84b
Time:2012-02-04T09:11:49.6479170Z" UserInfo=0x4573370 {AzureReasonCode=EntityAlreadyExists, NSLocalizedDescription=The specified entity already exists.
RequestId:c55fd56a-998d-4615-8eb1-ccfd3a10d84b
Time:2012-02-04T09:11:49.6479170Z}

I have done a lot of debugging to make sure the row 'really did not exist'. In fact, I cleaned out the rows from table storage using another tool. On the insert of the first row, I got this error.

To add another layer of complexity into the mix. This error only occurs when I have 2 separate blocks of code that access azure in the same method. the error is occurring in the 2nd block if the first block of code exists...notice that I said exists (The first block of code never runs - I set a variable in the if statement of 5000 and this condition is never met). If I comment out the first block of code, the error goes away.

This is really stumping me and I thought I would see if anyone has any ideas.

I have included the code below but it is not enough to run as is. Please substitute the values for the inserted objects with anything...hopefully can be reproduced. If no one can reproduce..I will try to create a working sample.

FIRST BLOCK....NEVER GETS EXECUTED AND WHEN COMMENTED OUT MAKES THE 2ND BLOCK NOT RETURN ERROR

------START OF FIRST BLOCK

NSPredicate *waPredicate = [NSPredicate predicateWithFormat:@"( PartitionKey = %@) && (RowKey = %@)",[appDelegate ntRestaurantID],[deleteItem rowKey]];
WATableFetchRequest *fetchRequest = [WATableFetchRequest fetchRequestForTable:[deleteItem tableName] predicate:waPredicate error:nil];
isRunningDeletedItem++;
[azureClient fetchEntities:fetchRequest withCompletionHandler:^(NSArray *entities, NSError *error)
{
if (error)
{
[appDelegate handleNexTableErrorsForError:error inClass:NSStringFromClass([self class]) inCommand:@"DeletedItems"];
}
else
{
if (entities.count == 0)
{
int counter = [deleteItem.deleteSynchCounter integerValue];
if (counter >= 10) {
[deleteItem setSynchStatus:@"OK"];
[[self synchObjectContext] deleteObject:deleteItem];

}
else
{
counter++;
[deleteItem setDeleteSynchCounter:[NSNumber numberWithInt:counter]];

}
}
else
{
WATableEntity *azureObject = [entities objectAtIndex:0];
long long interval = llabs([[appDelegate historyStartDate] timeIntervalSinceNow] * 10000000);
[azureObject setObject:[[NSNumber numberWithLongLong:interval]stringValue] forKey:@"lastUpdatedTick"];
[azureObject setObject:@"YES" forKey:@"deleted"];

isRunningDeletedItem++;
[azureClient updateEntity:azureObject withCompletionHandler:^(NSError *error)
{
//---------------------------------CtoA-STEP 3
if (error)
{
[appDelegate handleNexTableErrorsForError:error inClass:NSStringFromClass([self class]) inCommand:@"DeletedItems"];
}
else
{
[deleteItem setSynchStatus:@"OK"];
[[self synchObjectContext] deleteObject:deleteItem];

}
isRunningDeletedItem--;
}];
}
}
isRunningDeletedItem --;
}];

-----END OF FIRST BLOCK

-----2ND BLOCK OF CODE THAT RECEIVES ERROR AFTER THE INSERT STATEMENT WHEN FIRST BLOCK IS NOT COMMENTED OUT - ERROR IS RECEIVED AFTER [azureClient updateEntity:azureObject withCompletionHandler:^(NSError *error)..BUT ROW IS INSERTED INTO AZURE

NSPredicate* waPredicate = [NSPredicate predicateWithFormat:@"( PartitionKey = %@) && (RowKey = %@)",[appDelegate ntRestaurantID],[ntObject rowKey]];
WATableFetchRequest* fetchRequest = [WATableFetchRequest fetchRequestForTable:@"ReservationTable" predicate:waPredicate error:nil];
isRunningReservationTable++;
[azureClient fetchEntities:fetchRequest withCompletionHandler:^(NSArray *entities, NSError *error)
{
if (error)
{
[appDelegate handleNexTableErrorsForError:error inClass:NSStringFromClass([self class]) inCommand:NSStringFromSelector(_cmd)];
}
else
{
if (entities.count == 0)
{
//DO NOT INSERT IF THIS OBJECT IS DELETED
if (![appDelegate.ntRecentlyDeletedRowKeys containsObject:ntObject.rowKey]) {
WATableEntity *azureObject = [WATableEntity createEntityForTable:@"ReservationTable"];
[azureObject setPartitionKey:[appDelegate ntRestaurantID]];
[azureObject setRowKey:[ntObject rowKey]];
long long interval = llabs([[appDelegate historyStartDate] timeIntervalSinceNow] * 10000000);
[azureObject setObject:[[NSNumber numberWithLongLong:interval]stringValue] forKey:@"lastUpdatedTick"];
[ntObject setLastUpdatedTick:[[NSNumber numberWithLongLong:interval]stringValue]];
[azureObject setObject:[ntObject reservationRowKey] forKey:@"reservationRowKey"];
[azureObject setObject:[ntObject serviceDate] forKey:@"serviceDate"];
[azureObject setObject:[ntObject serviceType] forKey:@"serviceType"];
[azureObject setObject:[ntObject tableID] forKey:@"tableID"];
[azureObject setObject:[ntObject tableRowKey] forKey:@"tableRowKey"];
[azureObject setObject:@"NO" forKey:@"deleted"];
isRunningReservationTable++;
[azureClient insertEntity:azureObject withCompletionHandler:^(NSError *error)
{
//---------------------------------CtoA-STEP 3
if (error)
{
[appDelegate handleNexTableErrorsForError:error inClass:NSStringFromClass([self class]) inCommand:NSStringFromSelector(_cmd)];
}
else
{
[ntObject setSynchStatus:@"OK"];
}
isRunningReservationTable--;
}]; }
}
else
{
//DO NOT UPDATE IF THIS OBJECT IS DELETED
if (![appDelegate.ntRecentlyDeletedRowKeys containsObject:ntObject.rowKey]) {
WATableEntity *azureObject = [entities objectAtIndex:0];
if ([[azureObject objectForKey:@"lastUpdatedTick"] longLongValue] < [[ntObject lastUpdatedTick] longLongValue])
{
long long interval = llabs([[appDelegate historyStartDate] timeIntervalSinceNow] * 10000000);
[azureObject setObject:[[NSNumber numberWithLongLong:interval]stringValue] forKey:@"lastUpdatedTick"];
[ntObject setLastUpdatedTick:[[NSNumber numberWithLongLong:interval]stringValue]];
[azureObject setObject:[ntObject reservationRowKey] forKey:@"reservationRowKey"];
[azureObject setObject:[ntObject serviceDate] forKey:@"serviceDate"];
[azureObject setObject:[ntObject serviceType] forKey:@"serviceType"];
[azureObject setObject:[ntObject tableID] forKey:@"tableID"];
[azureObject setObject:[ntObject tableRowKey] forKey:@"tableRowKey"];

isRunningReservationTable++;
[azureClient updateEntity:azureObject withCompletionHandler:^(NSError *error)
{
//---------------------------------CtoA-STEP 3
if (error)
{
[appDelegate handleNexTableErrorsForError:error inClass:NSStringFromClass([self class]) inCommand:NSStringFromSelector(_cmd)];
}
else
{
[ntObject setSynchStatus:@"OK"];
}
isRunningReservationTable--;
}];
}
else
{
[ntObject setSynchStatus:@"OK"];

}
}

}
}
isRunningReservationTable--;
}];