SC9 modifying same facet twice during the same visit

Hi.

 

I have some troubles with Sitecore 9.

 

On form submit i write to FacetA.PropertyA.

 

Later during the same visit, i write to FacetA.PropertyB.

 

Each time I get this error:

"Operation #0, AlreadyExists, Contact {b8ae4c31-f187-0000-0000-0548ebbca8e0}, FacetA"

 

I use same method as stated here, and each XConnectClient has it's own Submit after i modified the data.

 

 

I tried a lot of different stuff, but no success so far. 

 

It works fine if i just submit FacetA.PropertyA. But it seems like there is a conflict, because i modify the same facet (although different property) twice, during the same visit.

  • Happy to take look if you could post your code.
  • That page has a few links depending on if the facet already exists. In your code are you checking if the facet is null before calling new facet() ?

    The first time, (ever not just in this session) the contact gets a value for the facet, you need to call the facet's constructor, after that you should just retrieve the facet from xConnect.
  • Here is a dirty example. The two code parts are run at different places during the same visit:

     

    var manager = Sitecore.Configuration.Factory.CreateObject("tracking/contactManager", true) as Sitecore.Analytics.Tracking.ContactManager;
    
                    if (manager != null)
                    {
                        using (XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
                        {
                            try
                            {
                                var xdbContact = ContactRepository.GetNewOrExistingXConnectContact(contact, client, manager);
    
                                if (xdbContact != null)
                                {
    
                                    // Retrieve facet by name
                                    var personal = xdbContact.GetFacet<PersonalInformation>(PersonalInformation.DefaultFacetKey);
    
                                    if (personal != null)
                                    {
                                        // Change facet properties
                                        personal.FirstName = submittedContact.firstname;
                                        personal.LastName = submittedContact.lastname;
    
                                        // Set the updated facet
                                        client.SetFacet(xdbContact, PersonalInformation.DefaultFacetKey, personal);
                                    }
                                    else
                                    {
                                        // Facet is new
                                        PersonalInformation personalInfoFacet = new PersonalInformation()
                                        {
                                            FirstName = submittedContact.firstname,
                                            LastName = submittedContact.lastname
                                        };
    
                                        FacetReference reference = new FacetReference(xdbContact, PersonalInformation.DefaultFacetKey);
    
                                        client.SetFacet(reference, personalInfoFacet);
                                    }
    
                                    client.Submit();
    
                                    manager.RemoveFromSession(contact.ContactId);
                                    Sitecore.Analytics.Tracker.Current.Session.Contact = manager.LoadContact(contact.ContactId);
                                }
                            }
                            catch (XdbExecutionException ex)
                            {
                                // Manage conflicts / exceptions
                            }
                        }
                    }
    
    
                    /*TEST1*/
                    var manager1 = Sitecore.Configuration.Factory.CreateObject("tracking/contactManager", true) as Sitecore.Analytics.Tracking.ContactManager;
    
                    if (manager1 != null)
                    {
                        using (XConnectClient client1 = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
                        {
                            try
                            {
                                var xdbContact1 = ContactRepository.GetNewOrExistingXConnectContact(contact, client1, manager1);
    
                                if (xdbContact1 != null)
                                {
    
                                    // Retrieve facet by name
                                    var personal = xdbContact1.GetFacet<PersonalInformation>(PersonalInformation.DefaultFacetKey);
    
                                    if (personal != null)
                                    {
                                        // Change facet properties
                                        personal.FirstName = submittedContact.firstname;
                                        personal.LastName = submittedContact.lastname;
    
                                        // Set the updated facet
                                        client1.SetFacet(xdbContact1, PersonalInformation.DefaultFacetKey, personal);
                                    }
                                    else
                                    {
                                        // Facet is new
                                        PersonalInformation personalInfoFacet = new PersonalInformation()
                                        {
                                            FirstName = submittedContact.firstname,
                                            LastName = submittedContact.lastname
                                        };
    
                                        FacetReference reference = new FacetReference(xdbContact1, PersonalInformation.DefaultFacetKey);
    
                                        client1.SetFacet(reference, personalInfoFacet);
                                    }
    
                                    client1.Submit();
    
                                    manager1.RemoveFromSession(contact.ContactId);
                                    Sitecore.Analytics.Tracker.Current.Session.Contact = manager.LoadContact(contact.ContactId);
                                }
                            }
                            catch (XdbExecutionException ex)
                            {
                                // Manage conflicts / exceptions
                            }
                        }
                    }

  • In reply to Kasper Kristensen:

    Ok, so the error message implies that you are trying to add a facet to a contact, but the facet already exists for the contact. For that to happen, "personal != null" is false. So it seems your code is not finding the facet for the contact. There are a few reasons that might happen, but I would suspect it has something to do with the way you are getting your contact from xConnect.

    Here's an example using ContactExpandOptions. Can you try it and see it works for you?

    if (!Tracker.Current.Contact.IsNew)
    {
        using (XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
        {
            var contactIdentifier = Tracker.Current.Contact.Identifiers.FirstOrDefault();
            var existingContact = client.Get<Contact>(new IdentifiedContactReference(contactIdentifier.Source, contactIdentifier.Identifier), new ContactExpandOptions(PersonalInformation.DefaultFacetKey));
    
            if (existingContact != null)
            {
                var personalFacet = existingContact.GetFacet<PersonalInformation>() ?? new PersonalInformation();
                personalFacet.FirstName = model.FirstName;
                personalFacet.LastName = model.LastName;
                client.SetFacet(existingContact, PersonalInformation.DefaultFacetKey, personalFacet);
                client.Submit();
            }
        }
    }

  • In reply to David Ruckman:

    I just checked, and you are right. Even though the contact is known, and the facets are already populated, the facets are not returned. Personal is always null.

     

    I tried using the ContactExpandOptions you mentioned, but it doesn't work.

     

    Here is my method:

    public static Sitecore.XConnect.Contact GetNewOrExistingXConnectContact(Sitecore.Analytics.Tracking.Contact xdbContact, XConnectClient client, ContactManager manager)
            {
                Sitecore.XConnect.Contact rv = null;
    
                if (xdbContact != null && xdbContact.IsNew)
                {
                    if (manager != null)
                    {
                        xdbContact.ContactSaveMode = ContactSaveMode.AlwaysSave;
                        manager.SaveContactToCollectionDb(xdbContact);
    
                        var identifier = new IdentifiedContactReference(Sitecore.Analytics.XConnect.DataAccess.Constants.IdentifierSource, xdbContact.ContactId.ToString("N"));
    
                        rv = client.Get<Sitecore.XConnect.Contact>(identifier, new Sitecore.XConnect.ContactExpandOptions());
                    }
                }
                else
                {
                    var anyIdentifier = xdbContact.Identifiers.FirstOrDefault();
    
                    rv = client.Get<Sitecore.XConnect.Contact>(new IdentifiedContactReference(anyIdentifier.Source, anyIdentifier.Identifier), new Sitecore.XConnect.ContactExpandOptions(PersonalInformation.DefaultFacetKey));
                }
    
                return rv;
            }

  • In reply to Kasper Kristensen:

    Did you try this method for getting the current contact?

    var contactIdentifier = Tracker.Current.Contact.Identifiers.FirstOrDefault();
    var existingContact = client.Get<Contact>(new IdentifiedContactReference(contactIdentifier.Source, contactIdentifier.Identifier), new ContactExpandOptions(PersonalInformation.DefaultFacetKey));

  • In reply to David Ruckman:

    It actually seems like the thing i were missing was the ExpandOptions. I tried setting it for alle my facets, and now it works. I'm not sure why it didn't work last time i tried it.
  • In reply to David Ruckman:

    I have created a custom facet and added to expand options still getting the same error.