Symfony2集合持久化唯一对象


Symfony2 collection persist unique Objects

我试图通过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 }

我哪里做错了?

之所以会发生这种情况,是因为在持久化时必须手动检查是否存在子类别。您可以使用datatransformer,或者将检查代码放在实体的addSubCategory方法中,甚至使用prePresist生命周期回调。逻辑如下:获取所有现有的子类别,然后循环浏览输入的子类别。如果在现有子类别中找到子类别,则向结果ArrayCollection中添加一个现有实体,而不是传递输入的子类别。以下是我在项目中使用的带有标签的相同任务的示例代码:

$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;