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