Exception when updating CustomerContact after upgrade to Commercer 11.8.3

Kristoffer Lindén
Member since: 2004
 

Hi!

After upgrade to 11.8.3 we get an exception when trying to update a customer contact.

//Change adress information and then update
BusinessManager.Update(customerAddress);

//Save customer Contact changes
currentContact.SaveChanges();

We now get this exception:

Invalid validators:
[0] Field 'CustomerGroup' has a wrong enum id '1'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: Mediachase.BusinessFoundation.Data.Meta.MetaObjectValidationException: Invalid validators:
[0] Field 'CustomerGroup' has a wrong enum id '1'.


Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace: 


[MetaObjectValidationException: Invalid validators:
[0] Field 'CustomerGroup' has a wrong enum id '1'.
]
   Mediachase.BusinessFoundation.Data.Meta.MetaObject.OnSaving() +425
   Mediachase.BusinessFoundation.Data.Meta.MetaObject.Save(Boolean forceSave) +71
   Mediachase.BusinessFoundation.Data.Meta.MetaObject.Save() +49
   Mediachase.BusinessFoundation.Data.Business.EntityObjectDefaultRequestHandler.Update(BusinessContext context) +636
   Mediachase.BusinessFoundation.Data.Business.EntityObjectDefaultRequestHandler.Execute(BusinessContext context) +744
   Mediachase.BusinessFoundation.Data.Business.BaseRequestHandler.Mediachase.BusinessFoundation.Data.Business.IRequestHandler.Execute(BusinessContext context) +55
   Mediachase.BusinessFoundation.Data.Business.BusinessManager.ExecutePipeline(IRequestHandler handler) +142
   Mediachase.BusinessFoundation.Data.Business.BusinessManager.ExecutePipelineInTransaction(IRequestHandler handler) +103
   Mediachase.BusinessFoundation.Data.Business.BusinessManager.Execute(Request request) +650
   Mediachase.BusinessFoundation.Data.Business.BusinessManager.Update(EntityObject target) +80
   Mediachase.Commerce.Customers.CustomerContact.SaveChanges() +1636
   Direktronik.Core.Controllers.Pages.CheckoutController.SaveShippingAddresses(CheckoutViewModel checkoutViewModel) in Z:\ProgramData\JetBrains\TeamCity\BuildAgent-Dev01-1\work\806cc4af7e390e00\Direktronik.Core\Controllers\Pages\CheckoutController.cs:892
   Direktronik.Core.Controllers.Pages.CheckoutController.Purchase(CheckoutPage currentPage, CheckoutViewModel checkoutViewModel, IPaymentMethodViewModel`1 paymentViewModel) in Z:\ProgramData\JetBrains\TeamCity\BuildAgent-Dev01-1\work\806cc4af7e390e00\Direktronik.Core\Controllers\Pages\CheckoutController.cs:826
   lambda_method(Closure , ControllerBase , Object[] ) +220
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +229
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +35
   System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +39
   System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +67
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.AsyncInvocationWithFilters.b__3d() +72
   System.Web.Mvc.Async.<>c__DisplayClass46.b__3f() +385
   System.Web.Mvc.Async.<>c__DisplayClass46.b__3f() +385
   System.Web.Mvc.Async.<>c__DisplayClass46.b__3f() +385
   System.Web.Mvc.Async.<>c__DisplayClass46.b__3f() +385
   System.Web.Mvc.Async.<>c__DisplayClass46.b__3f() +385
   System.Web.Mvc.Async.<>c__DisplayClass46.b__3f() +385
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.<>c__DisplayClass2b.b__1c() +38
   System.Web.Mvc.Async.<>c__DisplayClass21.b__1e(IAsyncResult asyncResult) +185
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +38
   System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +65
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +52
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38
   System.Web.Mvc.MvcHandler.b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +43
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +65
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +607
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +134

Any ideas?

Thanks!

/Kristoffer

#189695 Mar 23, 2018 8:18
  • Jafet Valdez
    Member since: 2016
     

    What does the customer your trying to save have as a CustomerGroup? Is it "Customer" perhaps?

    It seems to me like your table storing the metaenum fields might have gotten messed up.

    Running this query:

    SELECT *
    FROM [mcmd_MetaEnum]
    WHERE TypeName = 'ContactGroup'

    Do you see a row with the "Id" column set to 1 ?

    #189716 Edited, Mar 23, 2018 9:53
  • Erik Norberg
    Member since: 2012
     
    <p>Enter commerce manager and see which Contact Groups you have defined there.</p> <p>Then enter the CMS and create a new visitor group, drag in customer properties and choose customer group and see which groups are available in that drop down.</p> <p>Is there a difference?</p> <p>Does an iisreset solve the problem?</p> <p></p> <p>We got this same error in production when an administrator had created a new customer group and set it on a customer.</p> <p>Everytime we tried to update that customer it would fail in validation.</p> <p>My investigation lead me to believe that the CMS has a cache used for the vallidation (and visitor groups etcetera) but changes in commerce manager didn't invalidate the cache. Furthermore there didn't seem to be a timeout that ejected the cache either, the issue stayed with us for atleast a week until we made a deploy.</p> <p>The support has accepted it as a bug but it isn't public yet:</p> <p>https://world.episerver.com/support/Bug-list/bug/COM-6776</p>
    #189741 Mar 23, 2018 13:08
  • Quan Mai
    Member since: 2011
     

    Enter commerce manager and see which Contact Groups you have defined there.

    Then enter the CMS and create a new visitor group, drag in customer properties and choose customer group and see which groups are available in that drop down.

    Is there a difference?

    Does an iisreset solve the problem?

    We got this same error in production when an administrator had created a new customer group and set it on a customer.

    Everytime we tried to update that customer it would fail in validation.

    My investigation lead me to believe that the CMS has a cache used for the vallidation (and visitor groups etcetera) but changes in commerce manager didn't invalidate the cache. Furthermore there didn't seem to be a timeout that ejected the cache either, the issue stayed with us for atleast a week until we made a deploy.

    The support has accepted it as a bug but it isn't public yet:

    https://world.episerver.com/support/Bug-list/bug/COM-6776

    Didn't know it was you (who reported the bug). It is under review now. Was almost closed because it could be a major change. Luckily it's small enough to be included in Commerce 12.1 (likely)

    #189839 Edited, Mar 26, 2018 9:58
  • Erik Norberg
    Member since: 2012
     
    <div class="borderBottom"><a href="/forum/developer-forum/Episerver-Commerce/Thread-Container/2018/3/exception-when-updating-customercontact-after-upgrade-to-commercer-11.8.3/reexception-when-updating-customercontact-after-upgrade-to-commercer-11-82-3/">Quan Mai said:</a></div> <p>Didn't know it was you (who reported the bug). It is under review now. Was almost closed because it could be a major change. Luckily it's small enough to be included in Commerce 12.1 (likely)</p> <p>That is quite alright. There are more important things for you to know than who reported which bug. <img src="/Scripts/tinymce/plugins/emoticons/img/smiley-wink.gif" alt="wink" /></p> <p>I'm glad it wasn't closed then, having to tell our clients that they have to wait for a server reset before they can use new customer groups could prove embarrasing as well as an inconvenience. <img src="/Scripts/tinymce/plugins/emoticons/img/smiley-embarassed.gif" alt="embarassed" /></p>
    #189845 Mar 26, 2018 14:01
  • Quan Mai
    Member since: 2011
     

    Didn't know it was you (who reported the bug). It is under review now. Was almost closed because it could be a major change. Luckily it's small enough to be included in Commerce 12.1 (likely)

    That is quite alright. There are more important things for you to know than who reported which bug. wink

    I'm glad it wasn't closed then, having to tell our clients that they have to wait for a server reset before they can use new customer groups could prove embarrasing as well as an inconvenience. embarassed

    It's more of a way to start a conversation ;) . We treat bugs by their severity and their impact, as well as how would the fix look like (is it too big/too risky to worth the effort). The reporter would be in the bottom of the list - well, bugs reported by external sources will be given higher priority than bugs reported by QAs (given all other criteria are the same). Bugs reported by EMVPs get a slight boost in priority as well.

    #189846 Mar 26, 2018 14:06
  • Quan Mai
    Member since: 2011
     

    For future visitors: the bug COM-6776 has been fixed in Commerce 12.1.0. Cache validation has been added for Business Foundation MetaModel, to ensure it's correctly validated when you update the models in Commerce Manager. As always we recommend to upgrade to latest version. 

    #192087 May 06, 2018 21:08
  • Erik Norberg
    Member since: 2012
     

    Thanks Quan, but is it really necessary to keep it hidden until after it is "Closed, Fixed and tested"?

    Not being able to refer people on the forum to a registered bug before it is fixed and about to be released is something of a bother and hampers communication.

    #192103 May 07, 2018 15:24
  • Quan Mai
    Member since: 2011
     

    Not really. We tend to make the bug public as soon as possible, but that needs some cleanups - i.e. sensitive information must be removed, grammar errors and typos must be corrected. Someone (and sometimes, two people) needs to review all that, of course, so that takes time. 

    #192104 Edited, May 07, 2018 15:33
  • Erik Norberg
    Member since: 2012
     
    <p>Maybe not the review part but the sensitive information, grammar, typos could customer support fix before they close the issue?</p> <p>I mean the large gap in time from the issue gets closed to the bug becoming public is a period where i have no way of following the progress (and starts pestering customer support about updates <img src="/Scripts/tinymce/plugins/emoticons/img/smiley-innocent.gif" alt="innocent" />).</p>
    #192108 May 07, 2018 16:16
  • Quan Mai
    Member since: 2011
     

    Go for it - I mean you can always poke support for status update and they will push us for making it public. Yes it might not sound like the best way to do thing, but our process is to do a review of work items before creating the public release (someone from development team will review technical information and someone from documentation team will review anything else). The reason: doing things in batch is always faster - less interuption and less context switch. Unless the bug is needed then we leave it there.

    You can always tell support to make the bug public when you report it - btw. We will take care of such request on triage process.

    EDIT: I think I can ask my team to try to make a bug public on triage if possible - if it comes from external sources. 

    #192109 Edited, May 07, 2018 17:01
  • Kristoffer Lindén
    Member since: 2004
     

    Hi!

    Is there a workaround for this? We don't have the possibility to upgrade at this moment. 
    Thanks!

    /Kristoffer

    #196555 Sep 04, 2018 11:28
  • Quan Mai
    Member since: 2011
     

    Technically you can force a cache validation. However that is pretty risky as it's internal stuff. I will look into ir to see if there is a reasonable way to do it and get back to you

    #196557 Sep 04, 2018 11:40
  • Kristoffer Lindén
    Member since: 2004
     

    Thanks! Looks like it only happens for an old CustomerContact. If I create a new CustomerContact and use that one it works just fine.

    #196558 Sep 04, 2018 11:46
  • Quan Mai
    Member since: 2011
     

    I had a - kinda - bad news for you. The change to fix the bug Erik mentioned was to make BF depends on ISynchronizedObjectInstanceCache. It previously depended on an internal cache that you can't access.

    On the brighter side - that would make a valid argument to upgrade?

    #196560 Sep 04, 2018 14:06
  • Kristoffer Lindén
    Member since: 2004
     

    Well... I will try to have them upgrade, we want to do this of course. But we have to go to 12.something, right? Upgrade to the latest version of 11 is not enough?

    #196561 Sep 04, 2018 14:16
  • Quan Mai
    Member since: 2011
     

    For future visitors: the bug COM-6776 has been fixed in Commerce 12.1.0. Cache validation has been added for Business Foundation MetaModel, to ensure it's correctly validated when you update the models in Commerce Manager. As always we recommend to upgrade to latest version. 

    said bug was fixed in 12.1.0 so yes, it's recommended to upgrade to 12.1.0 at least. I would say 12.8.0 is preferred (as always, newer is better)

    #196562 Sep 04, 2018 14:18
  • Kristoffer Lindén
    Member since: 2004
     

    Of course if we change major we will go all the way to the top!

    #196563 Sep 04, 2018 14:19
  • Quan Mai
    Member since: 2011
     

    That's the spirit!

    #196564 Sep 04, 2018 14:21
  • Kristoffer Lindén
    Member since: 2004
     

    Hi!

    So I updated to 12.8, and the problem is still there! I did an iisreset, still doesn't work. Any idea what I'm missing?

    /Kristoffer

    #196613 Sep 05, 2018 16:30
  • Quan Mai
    Member since: 2011
     

    First, thumb up for the upgrade.

    Second, let's take a step back here. Perhaps the bug Erik mentioned was not the bug you were seeing. Can you post the full code that you are using? It looks like you were updating CustomerGroup to some invalid values .... 

    #196615 Sep 05, 2018 16:34
  • Kristoffer Lindén
    Member since: 2004
     

    Ok, so this is what we do when we get the error. It has been there for a while and is quite messy...

    if (this.User.Identity.IsAuthenticated)
    {
        var isOrgAddress = false;
        var isNewAddress = false;
        var currentContact = this._customerContext.CurrentContact.CurrentContact;
    
        var customerAddress =
            currentContact.ContactAddresses.FirstOrDefault(x => x.AddressId == shippingAddress.AddressId);
    
        if (customerAddress == null && _customerContext.CurrentContact.CurrentOrganization != null)
        {
            customerAddress =
                _customerContext.CurrentContact.CurrentOrganization.Addresses.FirstOrDefault(
                    a => a.AddressId == shippingAddress.AddressId);
    
            isOrgAddress = customerAddress != null;
        }
    
        if (customerAddress == null)
        {
            customerAddress = CustomerAddress.CreateInstance();
            isNewAddress = true;
        }
    
        this._addressBookService.MapModelToCustomerAddress(shippingAddress, customerAddress);
        customerAddress.AddressType = CustomerAddressTypeEnum.Shipping;
    
        if (shippingAddress.AddressId == null && !isOrgAddress)
        {
            currentContact.AddContactAddress(customerAddress);
        }
        else if (!isNewAddress)
        {
            BusinessManager.Update(customerAddress);
        }
    
        currentContact.SaveChanges();
    }

    The currentContact.SaveChanges(); triggers the error.

    #196616 Sep 05, 2018 16:46
  • Kristoffer Lindén
    Member since: 2004
     

    This code also triggers the error:

    private CustomerAddress CreateOrUpdateCustomerAddress(CurrentContactFacade contact, Address address)
    {
        var customerAddress = GetAddress(contact, address.AddressId);
        var isNew = customerAddress == null;
        IEnumerable<PrimaryKeyId> existingId = contact.ContactAddresses.Select(a => a.AddressId).ToList();
        if (isNew)
        {
            customerAddress = CustomerAddress.CreateInstance();
        }
    
        MapModelToCustomerAddress(address, customerAddress);
    
        if (isNew)
        {
            contact.AddContactAddress(customerAddress);
        }
        else
        {
            contact.UpdateContactAddress(customerAddress);
        }
    
        contact.SaveChanges();
        if (isNew)
        {
            customerAddress.AddressId = contact.ContactAddresses
                .Where(a => !existingId.Contains(a.AddressId))
                .Select(a => a.AddressId)
                .Single();
            address.AddressId = customerAddress.AddressId;
        }
        return customerAddress;
    }
    #196617 Sep 05, 2018 16:51
  • Kristoffer Lindén
    Member since: 2004
     

    And it is only old CustomerContacts. If I create a new CustomerContact everything works just fine so there is something with the old ones....

    #196620 Sep 05, 2018 17:02
  • Erik Norberg
    Member since: 2012
     

    I don't see it being a code issue at all but a Data issue.

    CustomerGroup on cls_contact in the database doesn't have a foreign key, therefore it is validated in code whenever you attempt to save a contact.

    In our case it was the cache that gave a wrong result but if your error persists you might have it in the database as well.

    SELECT TOP 1000 *
    FROM [EPiServer.Commerce].[dbo].[mcmd_MetaEnum]
    WHERE TypeName='ContactGroup'

    Do you even have one with Id=1 there?

    #196621 Sep 05, 2018 17:03
  • Quan Mai
    Member since: 2011
     

    I would need the code inside 

    MapModelToCustomerAddress
    #196622 Sep 05, 2018 17:04
  • Erik Norberg
    Member since: 2012
     

    If you doesn't you have to create it or update all contacts with CustomerGroup=1 to something that does exists.

    #196623 Sep 05, 2018 17:04
  • Kristoffer Lindén
    Member since: 2004
     
    public void MapModelToCustomerAddress(Address address, CustomerAddress customerAddress)
    {
        customerAddress.Name = address.Organization;
        customerAddress.City = address.City;
        customerAddress.CountryCode = address.CountryCode;
        customerAddress.CountryName = GetAllCountries().Where(x => x.Code == address.CountryCode).Select(x => x.Name).FirstOrDefault();
        customerAddress.FirstName = address.FirstName;
        customerAddress.LastName = address.LastName;
        customerAddress.Line1 = address.Line1;
        customerAddress.Line2 = address.Line2;
        customerAddress.DaytimePhoneNumber = address.DaytimePhoneNumber;
        customerAddress.PostalCode = address.PostalCode;
        customerAddress.RegionName = address.Region;
        // Commerce Manager expects State to be set for addresses in order management. Set it to be same as
        // RegionName to avoid issues.
        customerAddress.State = address.Region;
        customerAddress.Email = address.Email;
        customerAddress.AddressType =
            CustomerAddressTypeEnum.Public |
            (address.ShippingDefault ? CustomerAddressTypeEnum.Shipping : 0) |
            (address.BillingDefault ? CustomerAddressTypeEnum.Billing : 0);
    }
    #196624 Sep 05, 2018 17:11
  • Kristoffer Lindén
    Member since: 2004
     

    @Erik

    MetaEnumId Id TypeName FriendlyName OrderId Owner AccessLevel
    25 1 ContactGroup Customer 1 System 1
    26 2 ContactGroup Partner 2 System 1
    27 3 ContactGroup Distributor 3 System 1
    32 4 ContactGroup VIP 4 System 1

    Looks ok and as I said, it workd for a new CustomerContact. All old ones created before upgrading to 11.8 gives the exception.

    #196625 Sep 05, 2018 17:15
  • Erik Norberg
    Member since: 2012
     

    Can you edit those old customers in Commerce Manager without any issues?

    #196626 Sep 05, 2018 17:18
  • Erik Norberg
    Member since: 2012
     

    Is the metafield also ok?

    SELECT TOP 1000 *
    FROM [EPiServer.Commerce].[dbo].[mcmd_MetaField]
    WHERE Name='CustomerGroup'

    It is very strange that new customers works though, they have also CustomerGroup=1? and it is still the same exception as in your first post that you are getting?

    #196627 Sep 05, 2018 17:22
  • Kristoffer Lindén
    Member since: 2004
     

    Yes, I can edit the old contacts in the Manager, but I don’t think I’ve tried to update the address and that is when it fails. I’ll try that asap!

    #196628 Sep 05, 2018 17:33
  • Quan Mai
    Member since: 2011
     

    Your code looks like it was taken from Quicksilver - so it should work. This starts to look less like a bug, but more of something with your site. I'd suggest to contact our developer support service for further assistance. 

    #196640 Sep 06, 2018 7:30
  • Kristoffer Lindén
    Member since: 2004
     

    Hmm, looking at the contact object I have two(?) CustomerGroup.
    One string CustomerGroup and one CustomerGroup (Mediachase.Commerce.Customer.ContactEntity) int?

    Strange!? Is that correct?

    #196648 Sep 06, 2018 8:40
  • Quan Mai
    Member since: 2011
     

    Yes, it looks like you have a metafield (accidentally) added to CustomerContact class, try to look at this - perhaps remove it and try again?

    #196650 Sep 06, 2018 8:56
  • Kristoffer Lindén
    Member since: 2004
     

    Looks ok. I just found two rows in the cls_Contact table that actually for some reason has CustomerGroup = "1". And it is just these two accounts I have been testing with.
    How they got the value I don't know but when I set it to NULL we are fine.

    Strange, but mystery solved!

    Thanks for your time and help!

    #196653 Sep 06, 2018 10:14
  • Erik Norberg
    Member since: 2012
     

    That would mean that you probably never can use CustomerGroup at all.

    Did you do what Quan suggested and removed the duplicated CustomerGroup from the contact?

    The real one should look like in Quan's screenshot. (The Int one i think.)

    #196665 Sep 06, 2018 14:09
  • Kristoffer Lindén
    Member since: 2004
     

    No, there wasn't any double property for what I could see. It only looked like it in Visual Studio. No really sure why, but that wasn't the problem.

    #196666 Sep 06, 2018 14:24