0

I have a form container with save button . This is the method that the save button call.

public function saveAction(){
    $userId = Mage::getSingleton('admin/session')->getUser()->getId();
    $user = Mage::getModel('admin/user')->load($userId);
    $idSetting=$user->getShopsetting_entity_id();
    $setting=Mage::getSingleton('Name_Module/shopSetting')->load($idSetting);

    $setting->setData($this->getRequest()->getParam('shopSetting'));
    $setting->save();

    return $this->_redirect('*/*/index');
}

This method create another element in shopSetting_entity, but I want the attributes value is modified.

I also try using

$setting->setAttributeName($shopSetting['attribute_name']);
$setting->save();

But in this case Magento add a row in shopSetting_entity_int with same entity_type_id,attribute_id,store_id,entity_id and does not modify the old one.

(int is the type of attribute_name)

I also try with

$setting->setAttributeName($shopSetting['attribute_name']);
$setting->getResource()->saveAttribute($setting,'attribute_name');

But the result is always the same.

In particular case of the method saveAttribute of Mage_Eav_Model_Entity_Abstract I note that this method distinguishes between the update and insertion, this is the code:

....
 $select = $adapter->select()
                ->from($table, 'value_id')
                ->where($where);
            $origValueId = $adapter->fetchOne($select);

            if ($origValueId === false && ($newValue !== null)) {
                $this->_insertAttribute($object, $attribute, $newValue);
            } elseif ($origValueId !== false && ($newValue !== null)) {
                $this->_updateAttribute($object, $attribute, $origValueId, $newValue);
            } elseif ($origValueId !== false && ($newValue === null)) {
                $adapter->delete($table, $where);
            }
            $this->_processAttributeValues();
            $adapter->commit();
...

but _insertAttribute and _updateAttribute call the same method _saveAttribute

    protected function _insertAttribute($object, $attribute, $value)
{
    return $this->_saveAttribute($object, $attribute, $value);
}

....

    protected function _updateAttribute($object, $attribute, $valueId, $value)
{
    return $this->_saveAttribute($object, $attribute, $value);
}

maybe there's a bug

9
  • What is the dump of $user->getShopsetting_entity_id()? Can you try $user->getShopsettingEntityId()? Commented Aug 9, 2015 at 16:50
  • shopsetting entity_id is a name of a column that I associate to user, through this i can find the current setting. In shopSetting params there are the new values of setting that must take the place of old ones.
    – tonyB
    Commented Aug 9, 2015 at 16:56
  • I find that the problem is the setDate method, if i set all attributes individually everithing work fine. But If i don't want do this individually?
    – tonyB
    Commented Aug 9, 2015 at 16:59
  • Assuming the values are stored in an associative array with keys that match the column names in the database, you can do a foreach loop. I don't know if setData can handle arrays. Commented Aug 9, 2015 at 17:01
  • I discovered that it is not correct either do it individually because magento me add another element in the tables entity_int, entity_decimal, which are tables of attribute type that I am dealing
    – tonyB
    Commented Aug 9, 2015 at 17:19

2 Answers 2

1

If you call setData() with an array, the complete data gets replaced, this includes the ID.

So, if the result of $this->getRequest()->getParam('shopSetting') does not contain the ID, a new entity is created.

You probably are looking for addData() which sets only the attributes that exist in the passed array and leaves the rest as it is.

4
  • Ok, I also try using $setting->setAttributeName($shopSetting['attribute_name']); $setting->save(); But in this case Magento replicate a row in shopSetting_entity_int with same entity_type_id,attribute_id,store_id,entity_id . I have tried in many ways, but Magento only add new row does not modify the old one
    – tonyB
    Commented Aug 9, 2015 at 22:55
  • That means, you don't have duplicate entities, but duplicate attribute values for a single entity? I.e. (entity_id, attribute_id, store_id) are the same but (value) is different? Commented Aug 9, 2015 at 23:00
  • Yes i have duplicate attribute values for a single entity_id.
    – tonyB
    Commented Aug 9, 2015 at 23:06
  • The value is irrelevant in all cases Magento adds another row in the table
    – tonyB
    Commented Aug 9, 2015 at 23:09
0

I have detected the same problem on one of my custom EAV entity types.

When Magento updates EAV values, it uses an INSERT INTO with ON DUPLICATE KEY UPDATE to update the data in the eav tables.

An example query to update a value looks like this:

INSERT INTO `download_entity_varchar` 
(`entity_type_id`,`entity_id`,`attribute_id`,`value`)
VALUES (9, 6, 446, 'this is a value')
ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)

The MySQL documenation says:

If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, MySQL performs an UPDATE of the old row.

Comparing my custom table indizes to the indizes of catalog_product_entity_varchar I realized that there is one index missing on my table: the unique index over the columns entity_id, attribute_id and store_id.

So I added an unique index to my table after removing all duplicate entries, with this:

ALTER TABLE `download_entity_varchar`
ADD UNIQUE KEY `UNQ_DOWNLOAD_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID` 
(`entity_id`,`attribute_id`,`store_id`)

If you want to do it programmatically with an upgrade script (usually the smarter way), you just have to add the following lines and adjust the table name:

$table = 'download_entity_varchar';
$fields = ['entity_id', 'attribute_id', 'store_id'];
$indexType = Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE;

$indexName = $installer->getIdxName($table, $fields, $indexType);
$installer->getConnection()->addIndex($table, $indexName, $fields, $indexType);

This has to be done for each value type table, which are

  • _entity_char
  • _entity_datetime
  • _entity_decimal
  • _entity_int
  • _entity_text
  • _entity_varchar

After doing that, the values get updated correctly.

For me it seems to be a bug in Magento, that the unique index is not created in Mage_Eav_Model_Entity_Setup::createEntityTables.

1
  • After creating this answer, I found that there's someone else who answered to a similar question.
    – stollr
    Commented Sep 9, 2016 at 13:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.