Symfony2集合持久存在唯一的对象

时间:2013-02-26 18:43:09

标签: php symfony doctrine-orm

我正在尝试通过ManyToMany关系中的集合保存表单,问题是持久存在一个对象!

class Anagrafica
{
/**
 * @ORM\ManyToMany(targetEntity="SubCategories", inversedBy="anagrafiche", cascade={"persist", "remove"})
 * @ORM\JoinTable(name="AnCat")
 **/
private $subCategories;

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

/**
 * Add subCategories
 *
 * @param \My\BusinessBundle\Entity\SubCategories $subCategories
 * @return Anagrafica
 */
public function addSubCategory(\My\BusinessBundle\Entity\SubCategories $subCategories)
{
    $subCategories->addAnagrafiche($this);
    $this->subCategories[] = $subCategories;
}

*******
class SubCategories
{
/**
 * @ORM\ManyToMany(targetEntity="Anagrafica", mappedBy="subCategories")
 */
private $anagrafiche;

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

/**
 * Add anagrafiche
 *
 * @param \My\BusinessBundle\Entity\Anagrafica $anagrafiche
 * @return SubCategories
 */
public function addAnagrafiche(\My\BusinessBundle\Entity\Anagrafica $anagrafiche)
{
    $this->anagrafiche[] = $anagrafiche;
}

AnagraficaType:

//..
->add('subCategories', 'collection', array('type' => new SubCategoriesType(), 
                'allow_add' => true,
                'allow_delete' => true,
                'prototype' => true,
                'prototype_name' => '__categ__',
                'by_reference' => false
            ))

当我去保存时,即使我选择了数据库中已存在的子类别,他也会执行查询插入:

INSERT INTO SubCategories (subCategory, category_id) VALUES (?, ?)
Parameters: { 1: Object(Doctrine\Common\Collections\ArrayCollection), 2: 12 }

我在哪里做错了?

1 个答案:

答案 0 :(得分:1)

这是因为在持久化时手动检查子类别是否存在。您可以使用datatransformer或将检查代码放在实体的addSubCategory方法中,甚至可以使用prePresist生命周期回调。逻辑如下:您获得所有现有的子类别,然后遍历输入的子类别。如果在现有子类别中找到子类别,则向结果ArrayCollection添加现有实体,而不是传递输入的 new 子类别。以下是我在项目中使用的示例代码,用于标记相同的任务:

$existingSubcategories = $repository->findAll();

if (count($existingSubcategories) < 1)
    return $enteredSubcategories;

$resultCollection = new \Doctrine\Common\Collections\ArrayCollection();

foreach ($enteredSubcategories as $enteredSubcategory)
{
    $exists = false;
    foreach ($existingSubcategories as $existingSubcategory)
    {
        // compare them by any unique param
        if ($existingSubcategory->getName() == $enteredSubcategory->getName())
        {
            $exists = true;
            break;
        }
    }

    $resultCollection[] = ($exists === true) ? $existingSubcategory : $enteredSubcategory;
}

return $resultCollection;