Symfony克隆实体坚持旧实体

时间:2016-06-14 08:40:39

标签: symfony

我有一个带有两个提交按钮的表单,"保存并覆盖"和"另存为副本"。

所以这就是问题,当我用下一个代码创建副本时,旧实体仍在更新中:

'System.Data.SqlClient.SqlException' occurred in System.Data.dll
System.Data.SqlClient.SqlException (0x80131904): Incorrect syntax near the keyword 'user'.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReadeThe thread 'vshost.RunParkingWindow' (0x820) has exited with code 0 (0x0).
The thread '<No Name>' (0xc80) has exited with code 0 (0x0).

即使我分离它并显式调用flush($ copy)。

要处理深拷贝,我有下一个代码:

清单

public function EditAction($id, Request $request)
{
    $auth_checker = $this->get('security.authorization_checker');
    $token = $this->get('security.token_storage')->getToken();

    // Get our user from that token
    $user = $token->getUser();

    $em = $this->getDoctrine()->getManager();
    $checklist = $em->getRepository('AppBundle:Checklist')->find($id);


    if (!$checklist) {
        throw $this->createNotFoundException('Checklist not found... ' . $id);
    }

    $originalGroups = new ArrayCollection();
    $originalTasks = new ArrayCollection();
    $originalCorrectives = new ArrayCollection();

    /** @var ChecklistGroup $group */
    foreach ($checklist->getGroups() as $group) {
        $originalGroups->add($group);

        /** @var ChecklistTask $task */
        foreach ($group->getTasks() as $task) {
            $originalTasks->add($task);

            foreach ($task->getCorrectives() as $corrective) {
                $originalCorrectives->add($corrective);
            }


        }
    }


    $newTasks = new ArrayCollection();
    $newCorrectives = new ArrayCollection();

    $editForm = $this->createForm(ChecklistType::class, $checklist);

    $editForm->handleRequest($request);

    if ($editForm->isValid()) {
        foreach ($originalGroups as $group) {
            //$checklistgroup = $em->getRepository('AppBundle:ChecklistGroup')->find($group->getId());

            if (false === $checklist->getGroups()->contains($group)) {
                $checklistgroup = $em->getRepository('AppBundle:ChecklistGroup')->find($group->getId());
                $em->remove($checklistgroup);
            }
        }

        /** @var ChecklistGroup $newGroup */
        foreach ($checklist->getGroups() as $newGroup) {

            /** @var ChecklistTask $task */
            foreach ($newGroup->getTasks() as $task) {
                $newTasks->add($task);

                /* if(false === $originalTasks->contains($task)) {
                     $checklisttask = $em->getRepository('AppBundle:ChecklistTask')->find($task->getId());
                     $em->remove($checklisttask);
                 }*/
            }
        }

        foreach ($originalTasks as $originalTask) {
            if (false === $newTasks->contains($originalTask)) {
                $checklisttask = $em->getRepository('AppBundle:ChecklistTask')->find($originalTask->getId());
                $em->remove($checklisttask);
            }
        }

        /** @var ChecklistTask $newTask */
        foreach ($checklist->getGroups() as $newGroup) {
            /** @var ChecklistTask $task */
            foreach ($newGroup->getTasks() as $task) {
                foreach ($task->getCorrectives() as $lcorrective) {
                    $newCorrectives->add($lcorrective);
                }
            }
        }

        foreach ($originalCorrectives as $originalCorrective) {
            if (false === $newCorrectives->contains($originalCorrective)) {
                $checklistcorrective = $em->getRepository('AppBundle:ChecklistTaskCorrective')->find($originalCorrective->getId());
                $em->remove($checklistcorrective);
            }
        }

        $checklist->setUserModificator($user);

        if ($editForm->get('Save')->isClicked()) {
            $em->persist($checklist);
            $em->flush();
        }

        if ($editForm->get('SaveCopy')->isClicked()) {
            $copy = clone $checklist;

            $copy->setNombre($checklist->getNombre(). ' #COPY#');


            $em->persist($copy);
            $em->refresh($checklist);
            $em->flush();
        }


        $this->get('session')->getFlashBag()->add('success', "Se ha actualizado el Checklist correctamente.");

        return $this->redirectToRoute('listChecklist', array('id' => $id));
    }

    return $this->render(':checklist:create.html.twig', array(
        'edit' => true,
        'form' => $editForm->createView(),
    ));
}

ChecklistGroup

public function __clone()
{
    if ($this->id) {
        $this->setId(null);

        $groupsClone = new ArrayCollection();

        /** @var ChecklistGroup $group */
        foreach ($this->groups as $group) {
            $itemClone = clone $group;
            $itemClone->setChecklist($this);
            $groupsClone->add($itemClone);
        }
        $this->groups = $groupsClone;
    }
}

ChecklistTask

public function __clone()
{
    if ($this->id) {
        $this->id = null;

        // cloning the relation M which is a OneToMany
        $tasksClone = new ArrayCollection();

        /** @var ChecklistTask $task */
        foreach ($this->getTasks() as $task) {
            $itemClone = clone $task;
            $itemClone->setChecklistgroup($this);
            $tasksClone->add($itemClone);
        }
        $this->tasks = $tasksClone;
    }
}

ChecklistCorrective

public function __clone()
{
    if ($this->id) {
        $this->id = null;

        // cloning the relation M which is a OneToMany
        $correctivesClone = new ArrayCollection();

        /** @var ChecklistTaskCorrective $corrective */
        foreach ($this->getCorrectives() as $corrective) {
            $itemClone = clone $corrective;
            $itemClone->setChecklistTask($this);
            $correctivesClone->add($itemClone);
        }
        $this->correctives = $correctivesClone;
    }
}

结果是副本和原始核对表都存储了所有更改,例如,如果我添加一个组和两个任务,我将获得两个核对表实体及其组和任务。

同样在我所有的关系中,我坚持= {&#34; cascade&#34;},我不知道这可能是个问题。

出了什么问题?

修改

这是我在测试每个实体状态后得到的结果:

public function __clone()
{
    if($this->id) {
        $this->setId(null);
    }
}

群组,任务和纠正的现有实体看起来像托管,添加的实体看起来像新的,$ old_checklist看起来像DETACHED,$ copy看起来像MANAGED。

0 个答案:

没有答案