php - Symfony 表单集合:如何防止在 EntityManager->flush() 上重复插入?
问题描述
我有以下数据模型:
MainEntity.php
<?php declare(strict_type=1);
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class MainEntity
{
// $id, etc...
/**
* @ORM\OneToMany(
* targetEntity="App\Entity\RelationEntity",
* mappedBy="mainEntity",
* cascade={"persist", "merge", "remove"},
* orphanRemoval=true
* )
*/
protected Collection $sideRelations;
// getSideRelations(), setSideRelations($relations), addSideRelation($sideRelation), removeSideRelation($sideRelation)...
}
RelationEntity.php
<?php declare(strict_types=1);
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(
* name="main_side_relation",
* uniqueConstraints={
* @ORM\UniqueConstraint(name="id_pair", columns={"main_entity_id", "side_entity_id"})
* }
* )
*/
class RelationEntity
{
// $id, etc...
/**
* @ORM\Column(type="integer", nullable=false)
*/
protected ?int $relationValue;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\MainEntity", inversedBy="sideRelations")
* @ORM\JoinColumn(name="main_entity_id", referencedColumnName="id")
*/
protected MainEntity $mainEntity;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\SideEntity", inversedBy="mainRelations")
* @ORM\JoinColumn(name="side_entity_id", referencedColumnName="id")
*/
protected SideEntity $sideEntity;
// getRelationValue(), setRelationValue($relationValue), getMainEntity(), setMainEntity($mainEntity), getSideEntity(), setSideEntity($sideEntity)...
}
SideEntity.php
<?php declare(strict_types=1);
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class SideEntity
{
// $id, etc...
/**
* @ORM\OneToMany(
* targetEntity="App\Entity\RelationEntity",
* mappedBy="sideEntity",
* cascade={"persist", "merge", "remove"},
* orphanRemoval=true
* )
*/
protected Collection $mainRelations;
// getMainRelations(), setMainRelations($mainRelations), addMainRelation($mainRelation), removeMainRelation($mainRelation)...
我已经扩展了现有的 Symfony 表单类以适应数据模型。
RelationEntityType.php
<?php declare(strict_types=1);
namespace App\Form;
class RelationEntityType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('relationValue', HiddenType::class)
->add('mainEntity', HiddenType::class)
->add('sideEntity', HiddenType::class)
;
// Add Transformers to switch between Entity and database ID for input value
}
public function configureOptions(OptionsResolverInterface $resolver): void
{
$resolver->setDefaults(['data_class' => RelationEntity::class]);
}
}
MainEntityType.php
<?php declare(strict_types=1);
namespace App\Form;
class MainEntityType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
// ...
$builder->add('sideRelations', CollectionType::class, [
'required' => false,
'by_reference' => false,
'entry_type' => RelationEntity::class,
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true
]);
}
public function configureOptions(OptionsResolverInterface $resolver): void
{
$resolver->setDefaults(['data_class' => MainEntity::class]);
}
}
提交工作不像预期的那样,因为通过使用by_reference
我明确地删除并重新添加现有的未更改的集合条目,但是当省略该选项时它会隐式发生。
在这两种情况下,UnitOfWork
都填充了对现有集合条目的插入查询(并且由于唯一约束而引发错误)。我不想那样。
Symfony 的表单集合配置文档没有提供关于如何防止集合变得“脏”的有价值信息,尽管它们的条目在技术上没有改变。
我究竟如何避免覆盖未更改的现有集合条目?
(如有必要,我可以提供 MWE 的剩余代码)
解决方案
推荐阅读
- php - 如何根据条件拆分导航栏并更改链接
- rest - 在以客户身份登录之前从本机应用程序安全地访问 REST API
- python - MacOS Python 脚本可执行文件
- visual-studio-2019 - 在 nanoframework 中创建新的空白应用程序时包安装错误
- android - 如何在 Kotlin 中将字符串转换为关于“2021/03/03 00:51”的日期
- java - tabula 要求我在已安装最新版本时更新 java
- php - 将wordpress博客导入mysql数据库
- .htaccess - 移除 URL 参数 htacces
- javascript - 关于使用 Codeigniter 或其他可能的解决方案处理多维数组的建议?
- c# - 如何在 C# .NET(宽到长格式)中融化 DataTable?