Елемент (Mage_Sales_Model_Order) з тим самим ідентифікатором "X" вже існує


12

Після створення вантажу в адміністраторській області Magento, у var/reportпапці (після сторінки збою за програмою Magento за замовчуванням) в папці з'являється така помилка під час перегляду сторінки сітки замовлення адміністратора:

Item (Mage_Sales_Model_Order) with the same id "1234" already exist

Я можу позбутися цієї помилки, додавши пункт DISTINCT до селектора вибору об'єкта в app/code/core/Mage/Eav/Model/Entity/Collection/Abstact.phpрядку 662. Однак я дійсно не хочу цього робити з кількох причин (смертельно повільні запити, редагування основних файлів тощо).

Який найкращий спосіб вирішити це, зберігаючи цілісність даних. Чи слід видалити замовлення? Я би вдячний за будь-який конструктивний внесок, особливо про те, що спричинить цей конфлікт в першу чергу. Дякую.

- редагувати -

Ось повний слід стека для ясності / щоб вказати на мою дурість:

a:5:{i:0;s:67:"Item (Mage_Sales_Model_Order) with the same id "1234" already exist";i:1;s:4829:"#0 lib/Varien/Data/Collection/Db.php(576): Varien_Data_Collection->addItem(Object(Mage_Sales_Model_Order))
#1 app/code/core/Mage/Adminhtml/Block/Widget/Grid.php(533): Varien_Data_Collection_Db->load()
#2 app/code/core/Mage/Adminhtml/Block/Sales/Order/Grid.php(61): Mage_Adminhtml_Block_Widget_Grid->_prepareCollection()
#3 app/code/core/Mage/Adminhtml/Block/Widget/Grid.php(626): Mage_Adminhtml_Block_Sales_Order_Grid->_prepareCollection()
#4 app/code/core/Mage/Adminhtml/Block/Widget/Grid.php(632): Mage_Adminhtml_Block_Widget_Grid->_prepareGrid()
#5 app/code/core/Mage/Core/Block/Abstract.php(862): Mage_Adminhtml_Block_Widget_Grid->_beforeToHtml()
#6 app/code/core/Mage/Core/Block/Abstract.php(582): Mage_Core_Block_Abstract->toHtml()
#7 app/code/core/Mage/Core/Block/Abstract.php(526): Mage_Core_Block_Abstract->_getChildHtml('grid', true)
#8 app/code/core/Mage/Adminhtml/Block/Widget/Grid/Container.php(77): Mage_Core_Block_Abstract->getChildHtml('grid')
#9 app/design/adminhtml/default/default/template/widget/grid/container.phtml(36): Mage_Adminhtml_Block_Widget_Grid_Container->getGridHtml()
#10 app/code/core/Mage/Core/Block/Template.php(241): include('/var/www/html/m...')
#11 app/code/core/Mage/Core/Block/Template.php(272): Mage_Core_Block_Template->fetchView('adminhtml/defau...')
#12 app/code/core/Mage/Core/Block/Template.php(286): Mage_Core_Block_Template->renderView()
#13 app/code/core/Mage/Adminhtml/Block/Template.php(81): Mage_Core_Block_Template->_toHtml()
#14 app/code/core/Mage/Adminhtml/Block/Widget/Container.php(308): Mage_Adminhtml_Block_Template->_toHtml()
#15 app/code/core/Mage/Core/Block/Abstract.php(863): Mage_Adminhtml_Block_Widget_Container->_toHtml()
#16 app/code/core/Mage/Core/Block/Text/List.php(43): Mage_Core_Block_Abstract->toHtml()
#17 app/code/core/Mage/Core/Block/Abstract.php(863): Mage_Core_Block_Text_List->_toHtml()
#18 app/code/core/Mage/Core/Block/Abstract.php(582): Mage_Core_Block_Abstract->toHtml()
#19 app/code/core/Mage/Core/Block/Abstract.php(526): Mage_Core_Block_Abstract->_getChildHtml('content', true)
#20 app/design/adminhtml/default/default/template/page.phtml(74): Mage_Core_Block_Abstract->getChildHtml('content')
#21 app/code/core/Mage/Core/Block/Template.php(241): include('/var/www/html/m...')
#22 app/code/core/Mage/Core/Block/Template.php(272): Mage_Core_Block_Template->fetchView('adminhtml/defau...')
#23 app/code/core/Mage/Core/Block/Template.php(286): Mage_Core_Block_Template->renderView()
#24 app/code/core/Mage/Adminhtml/Block/Template.php(81): Mage_Core_Block_Template->_toHtml()
#25 app/code/core/Mage/Core/Block/Abstract.php(863): Mage_Adminhtml_Block_Template->_toHtml()
#26 app/code/core/Mage/Core/Model/Layout.php(555): Mage_Core_Block_Abstract->toHtml()
#27 app/code/core/Mage/Core/Controller/Varien/Action.php(390): Mage_Core_Model_Layout->getOutput()
#28 app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php(95): Mage_Core_Controller_Varien_Action->renderLayout()
#29 app/code/core/Mage/Core/Controller/Varien/Action.php(419): Mage_Adminhtml_Sales_OrderController->indexAction()
#30 app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(250): Mage_Core_Controller_Varien_Action->dispatch('index')
#31 app/code/core/Mage/Core/Controller/Varien/Front.php(176): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
#32 app/code/core/Mage/Core/Model/App.php(354): Mage_Core_Controller_Varien_Front->dispatch()
#33 app/Mage.php(683): Mage_Core_Model_App->run(Array)
#34 index.php(71): Mage::run('base', 'website')
#35 {main}";s:3:"url";s:72:"/index.php/admin/sales_order/index/key/0b7375aca52608483edc0cf879bd4361/";s:11:"script_name";s:10:"/index.php";s:4:"skin";s:5:"admin";}

8
FWIW Я ненавиджу цю тупу помилку і витратив більше часу, ніж мені байдуже визнати її налагодження.
philwinkle

Чи можете ви включити запит про колекцію чи php-код?
Сукешині

Відповіді:


10

Ви додали щось до колекції, що додає дублікатів до результату запиту.

Що magento робить з результатом запиту, це генерувати об’єкти з кожного рядка, а потім додавати ці елементи до колекції. Якщо елемент вже існує, ця помилка викидається.

Рішення: Що б ви не приєдналися, переконайтеся, що ваш результат чіткий.

Якщо ви додали більше полів поруч із sales_flat_orderполями, ці поля можуть відрізнятися, і тому вони відзначаються відфільтрованими за допомогою DISTINCT.


6

Я додаю відповідь, оскільки я ще не міг додати коментар. Я погоджуюся з @fabian - однак я перешкоджаю використанню DISTINCTі GROUP BY, як правило, ви можете відфільтрувати своє приєднання до єдиного чіткого результату, якщо плануєте правильно.

Наприклад (я знаю, це тривіальний приклад):

Якщо ви збирали замовлення за допомогою sales/flat_orderі ви приєдналися до адреси клієнтів, у двох записах зберігаються платіжна адреса та адреса доставки . Для вирішення цього питання можна вказати, який тип адреси вони хочуть приєднати.

Це звучить схоже на вашу ситуацію, за винятком не цього сценарію.


3

Ми також зіткнулися з деякими проблемами в нашій системі. Ми проаналізували проблему і знайшли мою Grid.php(наприклад: /namespace/modulename/Block/Adminhtml/Sales/Order/Grid.php)

Ми знайшли _prepareCollection()функцію у Grid.phpфайлі.

Помилка кодування:

//Error coding
$collection->join(array('payment' => 'sales/order_payment'), 'main_table.entity_id = parent_id', 'method')
            ->getSelect()
            ->where("`payment`.`method` like '%paypal%'");

Рішення:

//Solution coding
$collection->join(array('payment' => 'sales/order_payment'), 'main_table.entity_id = parent_id', 'method')
            ->getSelect()
            ->where("`payment`.`method` like '%paypal%'")
            ->group('method');

У нас є ->group('value')функція фільтра. Зараз прекрасно працює ... !!!


3

Я знаю, що це старе питання, і на нього вже відповіли, але я хочу додати свою відповідь, тому що я думаю, що це може допомогти іншим, хто стикається з подібними проблемами. Я намагаюся пояснити загальні причини такого типу помилок.

Для початку Mage_Sales_Model_Orderв стандартній установці Magento ніколи не слід давати таку помилку. Тож я підозрюю, що ця помилка викликана розширенням сторонніх розробників (спостерігач, метод гачка, перезапис тощо) або неправильним налаштуванням коду, яке в першу чергу пошкодило дані. Якщо говорити про основні компоненти, що діють "дивно", distinctрішення навіть не повинно існувати, оскільки дані не повинні були пошкоджуватися в першу чергу! Краще спочатку виправити самі дані, ніж змінити код.

Я зіткнувся з подібною проблемою, коли створив спеціальний тип сутності EAV, і все працювало нормально, поки я не відредагував одну з сутностей. Так чи інакше, редагування призвело до отримання дублюючого значення для одного з текстових атрибутів сутності, тобто двох рядків у таблиці значень тексту для того ж атрибута тієї ж сутності. Сирий запит лише на таблицю custom_entity виглядав ідеально добре, без дублікатів (як це могло бути? Обмеження первинного ключа вже забезпечило цілісність), тому проблема була десь в іншому місці.

Як ви вже здогадувались під час завантаження колекції, через з'єднання, які використовуються для отримання рядків із бази даних, та враховуючи, що для одного і того ж атрибута сутності було два однакові текстові значення, він отримав два рядки з однаковим entity_idзначенням, але різними value_id.

Як правило, при виникненні такої помилки ви повинні підозрювати, що або дані в базі даних вже пошкоджені, або що з'єднання, що відбуваються в результаті остаточного запиту, отримають два майже точних рядки з бази даних, дублюючи унікальний ідентифікатор колекції предметів.

Сподіваюсь, це допомагає.

PS: Щодо того, чому в моєму випадку дублюється значення тексту EAV, перегляньте коментар Маріуса тут http://inchoo.net/magento/creating-an-eav-based-models-in-magento/


0

Це мій код добре працює після того, як виникла така ж проблема:

    $collection = Mage::getResourceModel('sales/order_grid_collection');
    $prefix = Mage::getConfig()->getTablePrefix();  

    $collection->getSelect()->joinleft(array('order'=> $prefix.'sales_flat_order'),'order.entity_id=main_table.entity_id',array('pdeliverydate'));   

    $collection->getSelect()->joinleft(array('address'=> $prefix.'sales_flat_order_address'),'address.parent_id=main_table.entity_id',array('telephone'))->group('entity_id');

    $this->setCollection($collection);
    return parent::_prepareCollection();

У мене є add -> group ('entit_id') для вирішення проблеми.


Вже запропоновано 1 рік тому ( magento.stackexchange.com/a/139898/46249 ) ... -1.
sv3n

-1

ви повинні спробувати перекрити, Mage_Sales_Model_Resource_Order_Grid_Collection::addItemщо кидає це виняток:

<?php
class Fixed_Order_Grid_Collection extends Mage_Sales_Model_Resource_Order_Grid_Collection{

    public function addItem(Varien_Object $item)
    {
        $itemId = $this->_getItemId($item);

        if (!is_null($itemId)) {
            if (isset($this->_items[$itemId])) {
                //throw new Exception('Item ('.get_class($item).') with the same id "'.$item->getId().'" already exist');
            }
            $this->_items[$itemId] = $item;
        } else {
            $this->_addItem($item);
        }
        return $this;
    }
}
class MyCompony_MyExtention_Block_Adminhtml_OrderGrid extends Mage_Adminhtml_Block_Widget_Grid
{
     public function __construct()
    {
        parent::__construct();
        $this->setId('sales_order_grid');
        $this->setUseAjax(true);
        $this->setDefaultSort('created_at');
        $this->setDefaultDir('DESC');
        $this->setSaveParametersInSession(true);
    }
    protected function _getCollectionClass()
    {
        return 'sales/order_grid_collection';
    }

    protected function _prepareCollection()
    {
        $collection = new Fixed_Order_Grid_Collection();
        $select = $collection->getSelect();
        $select->join('sales_flat_order_item AS order_item', 'order_item.order_id=main_table.entity_id','quote_item_id',NULL);
        $select->distinct();
        $this->setCollection($collection);
        return parent::_prepareCollection();
    }
...

1
Це не рішення, а просто спосіб позбутися від повідомлення про помилку.
Нільс

1
Помилки сквошінгу - це не те саме, що виправляти їх, розгляньте можливість додавання виразних результатів до колекції або згрупуйте запит на приєднання за допомогою поля.
DWils
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.