Comment puis-je réparer «Article (Mage_Catalog_Model_Product) avec le même identifiant» xxx «existe déjà»?

18

J'ai eu cette erreur en essayant de filtrer une collection de produits

Item (Mage_Catalog_Model_Product) with the same id "6058" already exist et je voulais savoir ce qui pouvait causer l'erreur car il n'y a qu'un seul produit (visible) avec le même ID à l'intérieur de Magento.

Y a-t-il un tableau qui doit être effacé pour supprimer ce dupilcate?

user1704524
la source
Pouvez-vous ajouter du code? Vous devez utiliser group bypour obtenir uniquement un identifiant de produit unique. Voir magento.stackexchange.com/questions/12773/…
Renon Stewart
@RS, Salut, j'essaie toujours de trouver la cause, je
posterai

Réponses:

36

L'ajout du distinctcomme suggéré dans la réponse acceptée résout le problème mais présente des problèmes de performances. La base de données peut créer des tables temporaires sur le disque lors de l'exécution d'une requête avec distinctet cela ralentira votre demande. Vous pouvez à la place ajouter une groupcondition à la collection pour supprimer les doublons.

Jetez un oeil à ce post . Ce qu'ils ont fait (et je l'ai fait aussi) est groupé par l'ID d'entité. Cela devrait mieux fonctionner.

//adding filters to the collection..

$collection->getSelect()
           ->group('e.entity_id');
Vic
la source
pouvez-vous s'il vous plaît dire où nous devons ajouter ce code
Baby in Magento
@BabyinMagento où que vous soyez, vous utilisez votre collection dans votre code personnalisé. Cette erreur se produit lors de la création de modules personnalisés qui récupèrent des collections de la base de données. Cela peut apparaître si vous avez récemment installé des modules tiers. Dans ce cas, il appartient au développeur dudit module de rechercher l'emplacement de l'erreur.
Vic
La distinct()solution et cela supprimera tous les enregistrements supplémentaires de la requête, ce qui signifie que vous risquez de perdre des données sans le remarquer. Ce n'est donc peut-être pas la meilleure solution, comme dans mon cas. J'essaie maintenant de trouver un moyen d'obtenir les deux enregistrements de ma table jointe dans la collection afin de pouvoir afficher les deux enregistrements sur la même ligne dans la grille.
Jacques
Petite remarque: son importend de ne pas enchaîner cela à la collection, mais met d'abord votre colelction à une variable et que $ collection-> getSelect () -> group ('e.entity_id');
Rickert
où puis-je mettre à jour ce code?
zus
7

Normalement, il s'agit d'un bogue dans les données ou dans l'implémentation de la collection.

Voici une solution à un problème plus large. Cela fonctionne sur la collecte arbitraire, non seulement pour Catalog_Model_Product.

Étape 1. Modifier le fichier de base lib/Varien/Data/Collection.php, function addItem()mais , contrairement à cette réponse suggère, ne cache pas l'erreur.

Ajoutez plutôt des informations d'erreur supplémentaires à l'exception levée:

        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());
        }

Étape 2. Prenez la requête incriminée de votre rapport d'erreur et exécutez-la à la main. Voir quels enregistrements dupliquent la clé de collecte. Ajoutez order by <key field>au besoin.

Disséquez la requête en supprimant les tables participantes une par une et voyez quel enregistrement a provoqué la duplication.

Je crois que ce patch devrait être au cœur.

Victor Sergienko
la source
3

Votre problème est que vous avez une collection (probablement avec une jointure ou une union) qui entraîne le même produit chargé deux fois dans la collection.

Vous pouvez modifier la collection en cours de chargement en ajoutant une méthode distincte à l'objet de sélection.

Voir http://framework.zend.com/manual/1.12/en/zend.db.select.html

$db->select()
         ->distinct()

Mais cela s'accompagne de problèmes inhérents. L'utilisation de distinct entraînera la création de tables temporaires sur le disque, et non dans la mémoire, ce qui entraîne des pénalités de performances.

choco-loo
la source
0

Dans mon cas

->getSelect()->group('e.entity_id');

ne fonctionne pas j'utilise:

->getSelect()->group('main_table.entity_id');

Mat être aussi bien pour quelqu'un

Hassan Ali Shahzad
la source