У меня есть много-много двунаправленных отношений в Доктрине. Он связывает элементы с категориями. Проблема в том, что вначале я правильно отношу категорию к элементу, но когда я пытаюсь обновить категорию элемента, тогда она терпит неудачу с дублирующимся первичным ключом.
Это некоторые фрагменты кода, которые могут быть полезны:
/**
* @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);
}
ОБНОВИТЬ
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'
** ВТОРОЕ ОБНОВЛЕНИЕ **
Я добавил это if (is_object ($ item)) {$item-> removeExistingCategories(); } непосредственно перед:
if (count($selectedCategoriesIds) > 0) {
foreach ($selectedCategoriesIds as $selectedCategoryId) {
$category = $categoryRepo->find($selectedCategoryId);
и кажется, что он отлично работает, за исключением того, что теперь категории отображаются дважды в пользовательском интерфейсе, хотя таблица item_category была правильно заполнена.
Хорошо, последний вопрос, похоже, был отсортирован. Я допустил ошибку в итерациях itemsCategories. :)
Попробуйте удалить каскад в категории Категория... вы должны сделать это только на стороне владельца отношений (пункт в вашем случае).
update an item's category
?