2

I'm having the same problem as described in New Breeze 1.4.9 - Duplicate entity - possible bug?, however that problem was reported as being caused by a bug since fixed. I am using v1.4.11.

I'm finding that when I save a new Breeze entity to the server it reacts to the successful response from the server by creating a new, duplicate entity, instead of updating the existing one. I am running the following test code line-by-line in a browser console, from a state of having no entities in Breeze's cache.

EntityManager.createEntity("CustomGroup", properties);
EntityManager.getChanges(); =>
    0:
        Id="b0cb3194-35af-4d23-9e77-d192c907b566"
        EntityState=Added

So far, so good. As expected there is a single entity in the pending changes array.

EntityManager.saveChanges(); =>
    KeyMappings:
        0:
            TempValue="b0cb3194-35af-4d23-9e77-d192c907b566"
            RealValue="f056f519-9f11-4375-a0dd-5272a11b9b46"

After executing saveChanges(), the server returns a KeyMapping object with the temp and real key values. At this point, listing all entities in the cache reveals an unexpected result:

EntityManager.getEntities(); =>
    0:
        Id="f056f519-9f11-4375-a0dd-5272a11b9b46"
        EntityState=Added
    1:
        Id="b0cb3194-35af-4d23-9e77-d192c907b566"
        EntityState=Unchanged

So, while Breeze has changed the state of the original object to "Unchanged" in response to being saved to the server, it has not updated it with the new key, and has instead created a duplicate entity using the new key, which it thinks it still needs to save.

A 2nd call to saveChanges() sends a new request to the server, which responds with a KeyMapping object that has identical TempValue and RealValue, and at this point Breeze decides there are no more changes, although the rogue entity remains in the cache of course.

Community
  • 1
  • 1
Best Mamgu Ever
  • 303
  • 2
  • 10
  • Can you create a repro unit test using one of the DocCode models (found in the Breeze + Samples zip)?. So far I have been unable to repro your issue. – Jay Traband Apr 07 '14 at 18:12
  • I couldn't replicate the problem with the DocCode samples, but I've put together a very simple demo here: https://dl.dropboxusercontent.com/u/13860553/breeze-test.rar. Just run this through a local web server. I've put in static JSON files for the Metadata and to emulate the response from SaveChanges; both of these were just copied from real server responses that I got from our full .NET Web API project. Clicking the links logs relevant objects & details to the browser console to show what's happening with Breeze's cache before & after creating an entity and saving that entity to the server. – Best Mamgu Ever Apr 08 '14 at 16:53

2 Answers2

1

I looked at your Metadata.json, and I think the problem is there. OData metadata sometimes doesn't supply sufficient info. In this case, I don't think the Breeze client knows that ContentGroup has an auto-generated key.

We usually recommend using the WebApi Breeze ContextProvider and BreezeControllerAttribute instead of OData on the server. See the Breeze Documentation for some more reasons.

Steve Schmitt
  • 3,124
  • 12
  • 14
  • We encountered the problem of the auto-generated key early on and so we have this code in dataservice.js to set it on the client side: `var types = metadataStore.getEntityTypes(); for(var i in types){ types[i].autoGeneratedKeyType = breeze.AutoGeneratedKeyType.Identity; }` So I don't think that is the problem. (I noticed I accidentally left this commented out in the sample code, but I just checked again with it active). As an aside, we are already using the Web API Breeze ContextProvider and BreezeControllerAttribute, so we're not sure why we're having to set the autoGeneratedKeyType. – Best Mamgu Ever Apr 09 '14 at 13:24
  • Ah, sorry. If you're using Code First, I think you need to put an annotation on your Id property: `[DatabaseGenerated(DatabaseGeneratedOption.Identity)]` to make it appear in the metadata. – Steve Schmitt Apr 09 '14 at 19:26
  • Great, thanks Steve, that does seem to do the trick. We're still getting the duplicate entity problem, though. – Best Mamgu Ever Apr 10 '14 at 08:57
1

OK, I've figured it out. The entity returned by the server in the response from SaveChanges had the temporary key value, when it should have the new server-generated value. I had noticed this but assumed it was correct behaviour and would be sorted out by Breeze, using the KeyMapping, on receipt of the response.

I can't see anything in Breeze.ContextProviderEF6.EFContextProvider.cs that modifies the key value of the submitted entity, so this may be something that happens automatically in EntityFramework, but we need to do it manually in our custom LightSpeed ContextProvider.

Best Mamgu Ever
  • 303
  • 2
  • 10