How can I fix "Item (Mage_Catalog_Model_Product) with the same id "xxx" already exist"?
Adding the distinct
as suggested in the accepted answer does fix the problem but it has performance issues. The database might create temporary tables on disk when executing a query with distinct
and this will slow down your request. You can instead add a group
condition to the collection to remove duplicates.
Take a look at this post. What they did (and I have done it also) is group by the entity id. This should perform better.
//adding filters to the collection..
$collection->getSelect()
->group('e.entity_id');
Normally, this is a bug in the data or in the collection implementation.
Here's a solution to a broader issue. This works on arbitrary collection, not only for Catalog_Model_Product
.
Step 1. Modify the core file lib/Varien/Data/Collection.php
, function addItem()
, but unlike this answer suggests, don't hide the error.
Instead, add extra error information to the exception thrown:
if (isset($this->_items[$itemId])) {
throw new Exception('Item ('.get_class($item).
') with the same id "'.$item->getId().'" already exist' .
'. SQL that caused this: ' . $this->getSelect());
}
Step 2. Take the offending query from your error report and run it by hand. See what records duplicate the collection key. Add order by <key field>
as needed.
Dissect the query removing the participating tables one-by-one, and see which record caused the duplication.
I believe this patch should be in the core.
Your issue is that you have a collection (likely with a join or union) that is resulting in the same product being loaded into the collection twice.
You can alter the collection being loaded by adding a distinct method to the select object.
See http://framework.zend.com/manual/1.12/en/zend.db.select.html
$db->select()
->distinct()
But this comes with inherent problems. Using distinct will cause temporary tables to be created on disk, not in memory, which comes with performance penalties.