Doctrine ManyToMany on Same Entity Duplicate Entry

2019-04-26 09:28发布

I have to associate the same field with different parameters.

ManyToMany:

/**
 * @ORM\ManyToMany(targetEntity="BRCN\TaxonomyBundle\Entity\Taxonomy", mappedBy="genderCategories")
 */
private $genders;

/**
 * @ORM\ManyToMany(targetEntity="BRCN\TaxonomyBundle\Entity\Taxonomy", inversedBy="genders")
 * @ORM\JoinTable(name="menu_relations",
 *      joinColumns={@ORM\JoinColumn(name="gender_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")}
 *      )
 */
private $genderCategories;

These variables are using the same column name in the same table "id".

When i look at the "menu_relations" table, i see two primary key associated with my parameters.

When i try to insert new records, i'm getting this error:

An exception occurred while executing 'INSERT INTO menu_relations (gender_id, category_id) VALUES (?, ?)' with params [94, 1]:

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

Inserting values:

if($request->isXmlHttpRequest()) {
    $categories = $request->request->get('category');

    foreach($categories as $key => $value) {

        /** @var $gender \BRCN\TaxonomyBundle\Entity\Taxonomy */
        $gender = $em->find('BRCNTaxonomyBundle:Taxonomy', $key);

        if($gender) {

            foreach($value as $category) {
                $category = $em->find('BRCNTaxonomyBundle:Taxonomy', $category);

                $gender->addGenderCategory($category);
                $em->persist($gender);
            }

            $em->flush();
        }

    }

    return JsonResponse::create([
        'status' => true,
        'message' => 'İlişkilendirme Başarılı'
     ]);
}

1条回答
家丑人穷心不美
2楼-- · 2019-04-26 09:31

You could take advantage of Doctrine's indexed associations to avoid adding duplicate relationships.

The code below will index $genderCategories by category_id, so it will never contain more than one category with the same id.

Note the indexBy property in the annotations.

/**
 * @ORM\ManyToMany(targetEntity="BRCN\TaxonomyBundle\Entity\Taxonomy", inversedBy="genders", indexBy="id")
 * @ORM\JoinTable(name="menu_relations",
 *      joinColumns={@ORM\JoinColumn(name="gender_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")}
 *      )
 */
private $genderCategories;

public addGenderCategory($category) {
    $this->genderCategories[$category->getId()] = $category;
}

Sidenote

I suggest pulling the persist call out of your loop to improve performance.

foreach($value as $category) {
    $category = $em->find('BRCNTaxonomyBundle:Taxonomy', $category);
    $gender->addGenderCategory($category);
}

$em->persist($gender);
查看更多
登录 后发表回答