我们有一个使用Symfony2构建的调查构建应用程序(想想Survey Monkey或Google Forms)。当公众成员访问调查时,使用Symfony的表单生成器动态构建各种问题,并使用Doctrine持久保存他们的答案。我们目前每天平均收集1000份已完成的调查,没有任何问题,但是,我们一次又一次地获得Doctrine\DBAL
例外。
问题的每个答案都保存在一个表格中,该表格中包含一个唯一的密钥,该密钥由填写调查问卷的人员的 ID和他们正在回答的问题的ID 。有时,当Doctrine尝试INSERT
他们的答案时,会违反此密钥并且查询失败。正如我所提到的,这种情况很少发生,我们无法在我们的测试环境中复制它。
所有Symfony表单都是动态构建的,因此事情变得更加复杂。这是实际执行表单数据持久化的代码
public function save(\Symfony\Component\Form\Form $form, \Our\Namspace\Entity\Participant $participant)
{
/**
* $surveyReponse
*
* @var \Our\Namespace\Entity\SurveyResponse
*/
foreach ($form->getData() as $surveyResponseKey => $surveyResponse) {
$subQuestionId = $this->getQuestionIdFromSurveyResponseKey($surveyResponseKey);
$subQuestion = $this->getSubQuestionSettingsBySubQuestionId($subQuestionId);
if ($surveyResponse) {
$surveyResponse->setParticipant($participant)->setSubQuestion($subQuestion);
$participant->addResponse($surveyResponse);
$this->em->persist($surveyResponse);
}
$this->em->flush();
}
return true;
}
你可以看到我们在Form数据中编码问题的ID(在我们的域中称为SubQuestion)以获得(sub)Question实体,然后我们在上面设置Participant和SubQuestion SurveyResponse对象在持久化之前。 $this->em is
只是Doctrine Entity Manager。
如果没有看到所有代码,任何人都可能很难弄清楚发生了什么,但如果过去有人遇到类似的问题,也许他们可以提供一些建议。
我们可以而且应该在try / catch块中包装persist和flush操作然后处理异常,但我们真的想知道它为什么会发生!
SurveyResponse实体的相关位看起来像
class SurveyResponse implements SurveyAwareInterface
{
/**
* id of the response.
*
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* the subQuestion to which the response refers.
*
* @var SurveySubQuestion
*
* @ORM\ManyToOne(targetEntity="\Our\Namspace\Entity\SurveySubQuestion", inversedBy="surveyResponses")
* @ORM\JoinColumn(name="sub_question_id", referencedColumnName="id")
*/
protected $subQuestion;
/**
* the participant.
*
* @var AbstractParticipant
*
* @ORM\ManyToOne(targetEntity="Our\Namespace\Entity\Participant", inversedBy="responses")
* @ORM\JoinColumn(name="participant_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $participant;
实体中有这个注释;
* @ORM\Table(name="survey_response",
* uniqueConstraints= @ORM\UniqueConstraint(
* name="participant_response", columns={"participant_id", "sub_question_id"})})
*