DuplicateKeyException when using ObjectContainer

Thread is closed for posting
2 posts, 0 answers
  1. James Denning
    James Denning avatar
    24 posts
    Member since:
    Apr 2009

    Posted 26 Jun 2009 Link to this post

    Following on from the thread concerning usign one ObjectCOntainer on a disconnected client, I am now getting an error when using the same Container to add a new object then update another where the second update ChangeSet causes a duplicatekeyexception when commiting a Scope transaction as it tries to insert a duplicate of the new object added in the first ChangeSet from the Container. HEre is the sequence of events (the client is via WCF)

    1. Get a container from server to client
    2. Get reference data from server as a ChangeSet and apply to client container
    3. Create a new instance of a persisted object within client container transaction, attach reference objects from container
    4. Send changeset to server, apply, copy to scope and commit, receive ChangeSet via  GetContent()  from the server container and apply to client container.
    5. Retrieve another preexisting object from server via a GetContent() changeset applied ot client container from a fresh container on the server. Evict the original new object.
    6. Edit the preexisting object within client container transaction
    7. Send changes to server via GetChanges() the subsequent scope transaction Commit operation (after a CopyTo) on a scope fails with the DuplicateKeyException witht he data indicating it is trying to insert the object form the first phase.

    When I use a fresh container for the update phase on the client this error does not occur BUT I have then lost all my cached reference data and would have to refetch it from the server :( . The aim is to always use one container throughout the lifetime of the client application. AM i missing a step here? What ObjectContainer.Verfify modes should I be using in these scenarios?
  2. Alexander
    Alexander avatar
    727 posts

    Posted 29 Jun 2009 Link to this post

    Hello James Denning,

    The problem with the duplicating key is because OpenAccess tries to insert the same object twice. The solution is to use the "generateUpdateChanges" option of the ObjectContainer.CommitChanges() method. It can be enabled by passing "True" as last argument to the method and will cause the generation of a ChangeSet with the newly persisted object which you should send back to the client.
    I assume you have somewhere a method that applies the changes to an ObjectScope. If necessary, modify it so it should return the ChangeSet from the CommitChanges() method:
    public ObjectContainer.ChangeSet StoreAll(ObjectContainer.ChangeSet cs) 
       IObjectScope scope = ObjectScopeProvider1.ObjectScope(); 
       return ObjectContainer.CommitChanges(cs, ObjectContainer.Verify.All, scope, truetrue); 

    Then, on the client, apply this change set immediately after sending the changes to the server:
    ObjectContainer.ChangeSet set = service.StoreAll(container.GetChanges(ObjectContainer.Verify.All)); 

    Now the client will treat the the newly inserted object as expected - you can update it and store the changes again.
    About the ObjectContainer.Verify modes, All or Changed should work in this case. You can take a look at this help topic for a reference.

    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
Back to Top