-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Description
When saving a customer directly using the Customer Model custom attribute data is lost. This occurs when EAV caching is disabled. It appears you can get around this issue by using the Customer Repository or updateData function of the Customer Model. However, even though save is deprecated I would still expect it to work and looking into this has raised some concerns.
What I have found is that when saving directly some attribute set information is missing on the model, if we have a look at the aforementioned updateData function or the Customer Repository save function we see an acknowledgment of this issue in the form of a comment:
// Need to use attribute set or future updates can cause data loss
Below this comment both of these functions manually add an attribute set ID based on a hard-coded interface constant. I see no reason why this should not be done in the constructor, as that would get around this issue.
The saving process eventually leads to the checking of whether given attributes are in the expected attribute set using \Magento\Eav\Model\Entity\Attribute\AbstractAttribute::isInSet. What gets passed in this circumstance is null, as the attribute set for the Customer Model is not set. This results in the function returning false and then the attribute value gets deleted.
With regards to why this only occurs with EAV caching disabled. When it is enabled attribute_set_info is not defined on the attributes (what happens is the attribute is cached and then attribute_set_info is added manually afterwards) which is another issue - and one I am yet to fully understand. With attribute_set_info not set isInSet actually returns true and therefore the attribute value is not cleared down.:
if (!$this->hasAttributeSetInfo()) {
return true;
}
Preconditions
- Magento 2.2.0 or 2.1.7
Steps to reproduce
- Disable EAV cache.
- Create a custom attribute for Customer entity.
- Update a customer in the admin and add a value for this new attribute.
- Programmatically load the customer, make some change (e.g. firstname) and then save directly using the model.
Expected result
- When viewing the customer in the admin we will see the updated firstname and our previously saved custom attribute value.
Actual result
- The custom attribute value is lost.