javascript - 使用嵌入的表单集合保存相关 Doctrine 实体时出现 Symfony SQL 错误

标签 javascript php mysql symfony doctrine-orm

我一直关注How to Embed a Collection of Forms Symfony 网站上的示例。

我的情况有点不同。我有 2 个 Doctrine 实体 ExperimentGoal ,其 composite primary key关系(参见下面的代码)。

基本上,一个实验可以有多个目标,但目标ID仅在与实验 ID和用户组合时才是唯一的 ID。

class Goal
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", options={"default": 1})
     * @ORM\Id
     */
    protected $id = 1;

    /**
     * @var integer
     *
     * @ORM\Column(name="experiment_id", type="integer", nullable=true, options={"default": null})
     * @ORM\Id
     */
    protected $experimentId;

    /**
     * @ORM\ManyToOne(targetEntity="Experiment", inversedBy="goals")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="experiment_id", referencedColumnName="id"),
     *   @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
     * })
     */
    protected $experiment;

    /**
     * @var integer
     *
     * @ORM\Column(name="user_id", type="integer", nullable=true, options={"default": null})
     * @ORM\Id
     */
    protected $userId;

    /**
     * @ORM\ManyToOne(targetEntity="Optimcore\UserBundle\Entity\User", inversedBy="goals", cascade={"persist"})
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;

    // ...
}

我有一个 ExperimentType 表单,其中嵌入 GoalType 表单的 'collection'

在我的 Controller 中,我有以下代码:

$originalGoals = new ArrayCollection();
foreach ($experiment->getGoals() as $goal) {
    $originalGoals->add($goal);
}

$form = $this->createForm(new ExperimentType(), $experiment, array(
    'action' => $this->generateUrl('experiment_goals', array('id' => $experiment->getId())),
    'method' => 'PUT',
));
$form->handleRequest($request);

if ($form->isValid()) {
    $em = $this->getDoctrine()->getManager();

    // remove the relationship between the Goal and the Experiment
    foreach ($originalGoals as $goal) {
        if (false === $experiment->getGoals()->contains($goal)) {
            $goal->setExperiment(null);
            $em->persist($goal);
            $em->remove($goal);
        }
    }

    foreach ($experiment->getGoals() as $goal) {
        if (is_null($goal->getUserId())) {
            $this->getUser()->addGoal($goal);
            $goal->setUserId($this->getUser()->getId());
            $goal->setUser($this->getUser());
            $em->persist($goal);
        }
    }

    $em->flush();

}

我有 javascript 来添加和删除页面上的目标表单。新目标将分配下一个可用 ID,因此,如果页面上最后一个目标的 ID 为 2,则下一个目标的 ID 为 3。

添加新目标并保存到数据库工作正常,删除目标并保存也工作正常。

但是,当通过页面上的 javascript 删除目标,然后通过 javascript 添加新目标时,该目标将被分配与已删除目标相同的 ID。现在,当提交表单并且 Doctrine 尝试保存目标时,会引发 SQL 错误,因为 Doctrine 尝试插入一个与 Javascript 删除的目标具有相同 ID 但仍在数据库中的目标。

如何让 Doctrine 在插入新目标之前删除第一个目标?我之前尝试过冲洗,但这没有帮助。如何强制 Doctrine 在添加保存新目标之前仅删除旧目标?还是我的做法完全错了?

错误消息如下:

An exception occurred while executing 'INSERT INTO goal (id, experiment_id, user_id, name) VALUES (?, ?, ?, ?)' with params ["2", 183, 6, "Goal 2"]:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-183-6' for key 'PRIMARY'

最佳答案

Doctrine documentation 中找到了一个很长问题的非常简单的答案。 .

10.2. How Doctrine Detects Changes

  • Flush only a single entity with $entityManager->flush($entity).

为了让 Doctrine 在保存新目标之前删除原始目标,我必须在 $em->remove($goal) 之后添加 $em->flush($goal); ;。这将仅刷新该单个实体,并从数据库中删除该记录。

foreach ($originalGoals as $goal) {
    if (false === $experiment->getGoals()->contains($goal)) {
        $goal->setExperiment(null);
        $em->persist($goal);
        $em->remove($goal);

        // commit this change to the database
        $em->flush($goal);
    }
}

关于javascript - 使用嵌入的表单集合保存相关 Doctrine 实体时出现 Symfony SQL 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37076593/

相关文章:

javascript - 写入 Firestore 数据库会导致 Firestore net::ERR_BLOCKED_BY_CLIENT 错误

javascript - 如何在第 2 页加载时在第 1 页显示 Div 并在 setTimeout 后显示第 2 页

javascript - 为什么 1 ["foo"] 返回未定义而不是错误?

php - Symfony2 - 如何设置自定义 CORS header ?

javascript - 如何在 CodeIgniter 中集成 CKFinder 和 CKEditor?

mysql - mysql中如何用{}替换null值?

mysql - 按单个日期分解日期范围

javascript - Google 时区 API 的小时数不正确?

php - 如何获取事件的创建者?

mysql - SQL如何按关联计算项目