2015-02-11 2 views
0

У меня есть много-много двунаправленных отношений в Доктрине. Он связывает элементы с категориями. Проблема в том, что вначале я правильно отношу категорию к элементу, но когда я пытаюсь обновить категорию элемента, тогда она терпит неудачу, с дублированным первичным ключом.Многосторонние двунаправленные отношения с доктриной

Вот некоторые фрагменты из кода, который может быть полезным:

/** 
* @ORM\Table(name="item") 
* @ORM\Entity(repositoryClass="SomeBundle\Entity\Repository\ItemRepository") 
* 
*/ 
class Item 
{ 
/** 
    * @ORM\ManyToMany(targetEntity="Category", inversedBy="items", cascade={"persist"}) 
    **/ 
    private $categories; 
public function __construct() 
    { 
     $this->categories = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 
/** 
    * @param Item $item 
    */ 
    public function addItem(Item $item) 
    { 
     $this->items[] = $item; 
    } 

и

/** 
* Category 
* 
* @ORM\Table(name="category", indexes={@ORM\Index(name="category_parent", columns={"parent_id"})}) 
* @ORM\Entity(repositoryClass="SomeBundle\Entity\Repository\CategoryRepository") 
* @ORM\HasLifecycleCallbacks 
*/ 
class Category 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\ManyToMany(targetEntity="Item", mappedBy="categories", cascade={"persist"}) 
    * @ORM\JoinTable(name="item_category") 
    **/ 
    private $items; 

    public function __construct() 
    { 
     $this->items = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

    /** 
    * @param Category $category 
    */ 
    public function addCategory(Category $category) 
    { 
     $this->categories[] = $category; 
     $category->addItem($this); 
    } 

UPDATE

public function saveItem(Request $request) 
    { 
     $editMode = false; 
     $itemId = $request->request->get('item_id'); 

     if (isset($itemId) && $itemId > 0) { 
      $editMode = true; 
     } 

     $itemName = $request->request->get('itemName'); 
     $itemShortName= $request->request->get('itemShortName'); 

     $itemRepo = $this->getItemRepository(); 
     $item = $itemRepo->find($itemId); 

     // get last Item Id 
     if (!$editMode) { 
      $newItem = new Item(); 
      $newItemId = rand(1000, 6000); // TODO 
      $newItem->setId($newItemId); 
      $newItem->setSection('ar'); 
      // by default the item is inactive 
      $newItem->setActive(0); 
     } 

     //store the Item Type 
     $itemType = new ItemType(); 
     $itemType->setTypeId($request->request->get('itemType')); 

     if (!$editMode) { 
      $itemType->setItemId($newItemId); 
     } 

     // store the data into the ItemTranslation 
     if (!$editMode) { 
      $newItemTranslation = new ItemTranslation(); 
      $newItemTranslation->setItemId($newItemId); 
      $newItemTranslation->setLanguageId('1'); 
      $newItemTranslation->setItemName($itemName); 
      $newItemTranslation->ItemShortname($itemShortName); 
      $newItemTranslation->setTimestampAdd(new \DateTime()); 
      $this->em->persist($newItemTranslation); 
     } 

     //assign the respective Categories to the item 
     $selectedCategoriesIds = $request->request->get('itemCategories'); 
     $categoryRepo = $this->getCategoryRepository(); 

     if (count($selectedCategoriesIds) > 0) { 
      foreach ($selectedCategoriesIds as $selectedCategoryId) { 
       $category = $categoryRepo->find($selectedCategoryId); 
       if (is_object($item)) { //TODO 
        $item->addCategory($category); 
        $category->addItem($item); 

       } else { 
        $newItem->addCategory($category); 
        $category->addItem($newItem); 
       } 

       if (!$editMode) { 
        $this->em->persist($newItem); 
       } 
      } 
     } 

     $this->em->flush(); 
    } 

Сообщение об ошибке

An exception occurred while executing 'INSERT INTO item_category (item_id, category_id) VALUES (?, ?)' with params [2117, 1]: 

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2117-1' for key 'PRIMARY' 

** ВТОРОЕ UPDATE **

Я добавил этот если (is_object ($ пункт)) {$ item-> removeExistingCategories(); } непосредственно перед:

if (count($selectedCategoriesIds) > 0) { 
      foreach ($selectedCategoriesIds as $selectedCategoryId) { 
       $category = $categoryRepo->find($selectedCategoryId); 

и кажется, что он работает нормально, за исключением того, что теперь категории в настоящее время появились два раза в пользовательском интерфейсе, хотя item_category таблица была правильно заполнены.

ОК, последний вопрос, похоже, был отсортирован. Я допустил ошибку в итерациях itemsCategories. :)

+0

Возможно, нам потребуется увидеть контроллер (или где-нибудь еще проблема). Что вы подразумеваете под «обновлением категории товара»? –

+0

@caCtus Спасибо за ответ. Я имею в виду, что я могу захотеть обновить категории, к которым принадлежит элемент. – thitami

+0

Я обновил свой вопрос – thitami

ответ

0

Попробуйте удалить каскадный упор на объект категории ... вы должны сделать это только на стороне владельца отношений (пункт в вашем случае).

+1

Спасибо за ответ, @Stev. Я удалил его, как было предложено, и теперь я получаю ту же ошибку, когда я пытаюсь сохранить ту же категорию и добавить новую в элемент. Но когда я удаляю ранее существовавшую категорию и добавляю элемент в другую категорию, старая не удаляется, а новая сохраняется правильно. Надеюсь, что помогает. – thitami

+0

Прочтите эту статью http://symfony.com/doc/current/cookbook/form/form_collections.html. Особенно часть с доктриной Стойкость от конца. – Stev

Смежные вопросы