동일한 ID가“X”인 품목 (Mage_Sales_Model_Order)이 이미 존재합니다


12

Magento의 관리 영역에서 발송물을 생성 한 var/report후 관리 주문 그리드 페이지를 볼 때 폴더 에 다음 오류가 나타납니다 (기본 Magento 충돌 페이지 후).

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

app/code/core/Mage/Eav/Model/Entity/Collection/Abstact.php662 행 의 varien 객체 선택기에 DISTINCT 절을 추가하여이 오류를 제거 할 수 있습니다 . 그러나 몇 가지 이유로 인해 쿼리를 너무 느리게하거나 코어 파일을 편집하는 등의 작업을 원하지 않습니다.

데이터 무결성을 유지하면서이를 해결하는 가장 좋은 방법은 무엇입니까? 주문을 삭제해야합니까? 특히 처음에 이러한 충돌을 일으키는 원인에 대한 건설적인 의견에 감사드립니다. 감사.

-- 편집하다 --

명확성에 대한 전체 스택 추적은 다음과 같습니다.

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 코드를 포함시킬 수 있습니까?
Sukeshini

답변:


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

문제를 해결하기 위해-> group ( 'entity_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
이것은 해결책이 아니라 단순히 오류 메시지를 제거하는 방법입니다.
Niels

1
스 쿼싱 오류는 수정하는 것과 다릅니다. 수집 결과에 고유 한 항목을 추가하거나 조인 쿼리를 필드별로 그룹화하십시오.
DWils
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.