Symfony级联持久化或合并重复



我在级联持久化或合并方面有问题,我有一个具有两个实体任务和表(task_implements(的应用程序

当我创建任务时,我会选择链接的区域性:

  • 如果用户选择3种文化=>创建了3个任务
  • 如果用户选择3种培养物,则2辆车=>3项任务必须创建,每个任务绑定2辆车

TaskController new((

if ( $form->isSubmitted() && $form->isValid() ) {
// Cultures
foreach ( $form->get('cultures')->getData() as $culture) {
// Set correct status
if ( $task->getUser() === null ) {
$task->setStatus( 2 );
} else {
$task->setStatus( 3 );
}
$task->setCulture( $culture );
// Implements
foreach ( $form->get('implements')->getData() as $implement) {
$taskImplement = new TaskImplement();
$taskImplement->setImplement( $implement );
$task->addImplement( $taskImplement );
}
$this->em->merge( $task );
$this->em->flush();
}

$this->addFlash('success', 'Nouvelle tache ajoutée avec succès');
return $this->redirectToRoute('admin_task_index');
}

任务新类型

->add('implements', EntityType::class, [
'class' => Implement::class,
'query_builder' => function( ImplementRepository $ir ) {
return $ir->createQueryBuilder('i');
},
'choice_label' => function( Implement $implement ) {
return $implement->getName();
},
'mapped' => false,
'required' => false,
'expanded' => true,
'multiple' => true
])

任务实体

/**
* @ORMOneToMany(targetEntity=TaskImplement::class, mappedBy="task", orphanRemoval=true, cascade={"persist", "merge"})
*/
private $implements;
public function addImplement(TaskImplement $taskImplement): self
{
if (!$this->implements->contains($taskImplement)) {
$this->implements[] = $taskImplement;
$taskImplement->setTask($this);
}
return $this;
}

所需行为

举个例子,如果我选择3种文化,应用程序将创建3个任务,并在每个任务中创建2个实现绑定

id / culture_id
#1 10
#2 11
#3 12

在任务中_实现

id / task_id / implement_id
#1 1 20
#2 1 21
#3 2 20
#4 2 21
#5 3 20
#6 3 21

我得到的

id / culture_id
#1 10
#2 11
#3 12

关于任务实现

id / task_id / implement_id
#1 | 1 | 20 @
#2 | 1 | 21 
#3 | 2 | 20 @
#4 | 2 | 21 @
#5 | 2 | 20 @
#6 | 2 | 21 
#7 | 3 | 20 @
#8 | 3 | 21 @
#9 | 3 | 20 @
#10 | 3 | 21 @
#11 | 3 | 20 @
#12 | 3 | 21

我不明白为什么DB中的每个记录之间都不清楚,如果我在最后一个TaskImplement 上放入4个区域性,它就会重复

感谢您的帮助

显然,merge每次调用时都会创建一个新的任务条目(这可能意味着$task没有id。

在外部foreach的第一个周期中,您添加了2个TaskImplements,它们也没有id。您的任务现在有2个TaskImplements(这正是您目前想要的(。

在外部foreach的第二个周期中,您添加了另一个2个TaskImplements-现在您的任务中有4个TaskImplants。

解决方案选项:

  • 您需要在第一个外部foreach之后停止添加TaskImplements(这很奇怪,但会起作用(,或者
  • 设置您的任务实现,而不是添加它们或
  • 在添加新的任务实现或
  • 你"克隆";添加任务之前的任务实现了(只创建一个新任务就足够了?(

事后思考

merge的使用非常有趣。使用persistent,您应该只有一个任务,该任务包含6个TaskImplement,并且只有最后一个区域性集。老实说,在任务中没有id的情况下进行合并感觉像是一种反模式。

我认为,表单本身具有data_type Task,这本质上是错误的,因为您正在编辑/创建多个任务。您可以处理表单,就好像您有多个任务,但只有一个任务。你问题的根源在于错误的语义。。。

没关系,我在提交时用控制器代码做到了这一点

if ( $form->isSubmitted() && $form->isValid() ) {
// Cultures
foreach ( $form->get('cultures')->getData() as $culture) {
// Set correct status
if ( $task->getUser() === null ) {
$task->setStatus( 2 );
} else {
$task->setStatus( 3 );
}
$task->setCulture( $culture );
$this->em->persist( $task );
// Implements
foreach ( $form->get('implements')->getData() as $implement) {
$taskImplement = new TaskImplement();
$taskImplement->setImplement( $implement );
$taskImplement->setTask( $task );
$this->em->persist( $taskImplement );
}
$this->em->flush();
$this->em->clear( Task::class );
$this->em->clear( TaskImplement::class );
}

$this->addFlash('success', 'Nouvelle tache ajoutée avec succès');
return $this->redirectToRoute('admin_task_index');
}

我只是在每个上清除两个实体

工作是吗

最新更新