我试图模拟两个实体之间的可选一对一关系,当没有实际值时,使用默认的哨兵值。
实体(或多或少)如下:
拥有实体:
AcmeBundle\Entity\Issue:
type: entity
table: Issues
repositoryClass: AcmeBundle\Entity\IssueRepository
id:
id:
type: integer
id: true
generator:
strategy: AUTO
manyToOne:
story_1:
targetEntity: \AcmeBundle\Entity\Story
story_1a:
targetEntity: \AcmeBundle\Entity\Story
story_1b:
targetEntity: \AcmeBundle\Entity\Story
依赖实体:
AcmeBundle\Entity\Story:
type: entity
table: Stories
repositoryClass: AcmeBundle\Entity\StoryRepository
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
title:
type: string
length: 255
nullable: false
etc...
使用实体表单创建问题。 Story实体也有一个实体表单,其上有一个ModelDataTransformer,用于处理从表单中将空的Story替换为sentinel Story。
什么是假设要发生的是,当表单提交空故事时,ModelDataTransformer将它们与sentinel交换(它在调试器中验证),FormHandler会持续发出问题并刷新这一切都在数据库中。
问题在于,在执行flush时,它不是使用sentinel值,而是尝试插入完全空的Story实体并导致IntegrityErrors,因为不允许使用空的Story实体。
我已经完成了整个 EntityManager-> flush()过程,在此过程中,它完全保留了正确的标记数据。但出于某种原因,在实际执行插入之前,它会将所有内容交换为空的Story数据,然后崩溃到停止运行。
作为参考,我包括来自DataTransformer和FormHandler的片段,以防我在那里做了一些完全错误的事情。这一切都没有任何意义,似乎一切都设置正确,但它失败了。
DataTransformer(摘录):
public function reverseTransform($value)
{
if ($value === null || $value->getId() === null) {
return $this->om
->getRepository('AcmeBundle:Story')
->getNullStory();
}
return $value;
}
FormHandler(摘录):
$t = $this->om->getRepository('AcmeBundle:Story')->getNullStory();
$this->issue->setStory1($t);
$this->issue->setStory1a($t);
$this->issue->setStory1b($t);
$this->om->flush();
请注意,提供的FormHandler是"螺旋它,只是试着保存一个该死的哨兵,不管是什么因为我疯狂地沮丧"版。我已经尝试了几种处理故事设置的排列方式,包括在设定问题之前坚持哨兵故事,在设定问题后坚持哨兵,甚至根本没有设置任何东西并且让Doctrine弄明白。我试过的每一种方式都会得到相同的结果。
希望我提供了足够的信息。为简洁起见,我选择了代码段,但如果要求,我可以包含完整代码。