我一直在關注Symfony網站上的How to Embed a Collection of Forms示例。使用嵌入的表單集合保存相關的Doctrine實體時出現Symfony SQL錯誤
我的情況有點不同。我有2個學說實體Experiment
和Goal
與composite primary key的關係(見下面的代碼)。
基本上一個Experiment
可以有很多Goals
,但目標ID只有與Experiment
ID和User
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'
形式。
在我的控制器我有以下代碼:
$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刪除的目標相同的目標,但仍然存在於數據庫中。
在插入新的目標之前,我該如何去取得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'