I recently got a call from a client that has a Magento cart. He was getting an error when saving a product:
#1062 - Duplicate entry '59-0-1-229' for key 1
I wanted to do a quick writeup because it was a rather difficult one to debug and solve. After duplicating the error, I first tried to reindex the database tables. However, the “Product Prices” tabel was giving an error and couldn’t be saved.
I logged into the server and check the execption log. It didn’t give me much more info:
exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '59-0-1-229' for key 1' in /home/print/public_html/shop/lib/Zend/Db/Statement/Pdo.php:228
Stack trace:
#0 /home/print/public_html/shop/lib/Zend/Db/Statement/Pdo.php(228): PDOStatement->execute(Array)
#1 /home/print/public_html/shop/lib/Zend/Db/Statement.php(300): Zend_Db_Statement_Pdo->_execute(Array)
#2 /home/print/public_html/shop/lib/Zend/Db/Adapter/Abstract.php(479): Zend_Db_Statement->execute(Array)
#3 /home/print/public_html/shop/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query('INSERT INTO `ca...', Array)
#4 /home/print/public_html/shop/lib/Varien/Db/Adapter/Pdo/Mysql.php(333): Zend_Db_Adapter_Pdo_Abstract->query('INSERT INTO `ca...', Array)
#5 /home/print/public_html/shop/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Indexer/Price/Default.php(449): Varien_Db_Adapter_Pdo_Mysql->query('INSERT INTO `ca...')
#6 /home/print/public_html/shop/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Indexer/Price/Default.php(120): Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price_Default->_applyCustomOption()
#7 /home/print/public_html/shop/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Indexer/Price.php(377): Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price_Default->reindexAll()
#8 /home/print/public_html/shop/app/code/core/Mage/Index/Model/Indexer/Abstract.php(125): Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price->reindexAll(.....
Notice how the query error left out the actual query. At this point I figure there’s something wrong with a table somewhere. There are 250 tables in a Magento database, where to start? It has to be something to do with products, but that doesn’t narrow it down much, there are many tables dealing with products.
Then I tried a global search on the database from phpMyAdmin for the
duplicate key 59-0-1-229, but it turned up no results.
After much trial and error, a database dump and reimport, and more, I decided to focus on finding the query that was causing the error.
I found this article on how to get more detailed exception logging. Basically we’re modifiying the logException function rather than the “string” version of the error. The code I used from the article didn’t change anything for me, so here’s basically what I did:
* Write exception to log
*
* @param Exception $e
*/
public static function logException(Exception $e)
{
if (!self::getConfig()) {
return;
}
$file = self::getStoreConfig('dev/log/exception_file');
//comment out the below line
//self::log("\n" . $e->__toString(), Zend_Log::ERR, $file);
//add the below line
self::log($e, Zend_Log::ERR, $file);
}
This will give you a huge dump of info into the
app/var/log/exception.log file. From there I was actually able to see
the sql querry causing the problem.
INSERT INTO `catalog_product_index_price_opt_agr_idx` SELECT `i`.`entity_id`, `i`.`customer_group_id`, `i`.`website_id`, `o`.`option_id`, IF((@price:=IF(IF(ops.option_price_id>0, ops.price_type, opd.price_type)='fixed', IF(ops.option_price_id>0, ops.price, opd.price), ROUND(i.price * (IF(ops.option_price_id>0, ops.price, opd.price) / 100), 4))) AND o.is_require, @price,0) AS `min_price`, @price AS `max_price`, IF(i.base_tier IS NOT NULL, IF((@tier_price:=IF(IF(ops.option_price_id>0, ops.price_type, opd.price_type)='fixed', IF(ops.option_price_id>0, ops.price, opd.price), ROUND(i.base_tier * (IF(ops.option_price_id>0, ops.price, opd.price) / 100), 4))) AND o.is_require, @tier_price, 0), NULL) AS `tier_price` FROM `catalog_product_index_price_final_idx` AS `i`
INNER JOIN `core_website` AS `cw` ON cw.website_id = i.website_id
INNER JOIN `core_store_group` AS `csg` ON csg.group_id = cw.default_group_id
INNER JOIN `core_store` AS `cs` ON cs.store_id = csg.default_store_id
INNER JOIN `catalog_product_option` AS `o` ON o.product_id = i.entity_id
INNER JOIN `catalog_product_option_price` AS `opd` ON opd.option_id = o.option_id AND opd.store_id = 0
LEFT JOIN `catalog_product_option_price` AS `ops` ON ops.option_id = opd.option_id AND ops.store_id = cs.store_id
The first thing I did was copy and paste the query into mysql to make
sure I was getting the same result, and sure enough I got the same
Dtable I checked was the duplicate entry error:
#1062 - Duplicate entry '59-0-1-229' for key 1
I tried deleteing the catalog_product_index_price_opt_agr_idx table
first. Magento rebuilt it back, but with the same error. This is when
I took a closer look at the keys on the table. This is when I see there
is a unique key on fields:
entity_id, customer_group_id, website_id, option_id
That’s when it hits me that the 59-1-1-229, are those field values:
entity_id 59
customer_group_id 0
website_id 1
option_id 229
Then I go and check product #59 for an option 229, but theere isn’t one.
So I go into the catalog_product_option table and delete option 229.
Then I save a product and get no error. Also all tables will now index
properly.
I can only figure that that option must have been deleted at some point,
but never got completely deleted from the options table. A new option
took it’s place, but now was causing a duplicate.
Moral: logging and being able to read logs can help tremendously!








