使用Doctrine / Symfony2 prePersist / preUpdate Listeners时出现问题。
ManyToOne关系中有两个实体(一个位置可以被许多人引用)。我构建了一个Form,在那里我做了一些AJAX-Stuff来帮助用户为已经存在的新Person选择一个Location。因此,我使用的是“entity_id”Form-Field。 我还想让用户为数据库中不存在的新Person创建新位置。这由表单中的第二个字段处理,用户可以在其中插入新位置的名称。 当持久化Person的实体时,我正在检查数据库中是否存在引用的位置。如果没有,我正在生成一个新的Location-Entity。这是(简而言之)我在实体级人员中的prePersist-Lifecyclecallback:
public function prePersist() {
if($this->ort == null)
$this->ort = new Ort($this->ortsname);
}
当我创建一个新Person时,这非常有效。问题是更新程序。因此,当之前有一个位置连接到该人,并且我想通过相同的过程(使用preUpdate-Listener)创建一个新位置时,我收到一条通知,如:
Notice: Undefined index: 000000004a0010250000000058426bec in ...Doctrine/ORM/UnitOfWork.php line 983
我不知道如何解决这个问题。我认为必须使用Location-Object,这是在引用Person对象之前,但我不知道如何告诉Entity-Manager,引用Person的Location-Object是一个新的Entity。 我也尝试使用Listener-Class,如:
if( $entity instanceof Person) {
if( $entity->getLocation() == null ) {
$entity->setLocation( new Location( $entity->getLocatioName() );
$em->persist($entity->getLocation());
$em->flush();
}
}
$ em-> persist ...东西应该无关紧要,因为在映射中启用了“cascade = {persist}”表示法。
答案 0 :(得分:2)
我认为你会遇到preUpdate
的问题。有两件事意味着preUpdate
不是这种情况下最好的事件处理程序:
(这两点取自本节的底部:http://docs.doctrine-project.org/en/2.0.x/reference/events.html#preupdate)
此外,当在Doctrine的刷新操作中调用preUpdate
时,再次调用flush
会导致问题。
因此,我建议您改为使用onFlush
:http://docs.doctrine-project.org/en/2.0.x/reference/events.html#onflush
如果你这样做,你需要告诉Doctrine,一旦你为它添加了位置,Person实体就已经改变了。获取更改的Person对象本身也稍微复杂一些。在onFlush
处理程序中尝试这样的事情:
public function onFlush(OnFlushEventArgs $args)
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityUpdates() AS $entity) {
if ($entity instanceof Person) {
if ($entity->getLocation() == null ) {
$entity->setLocation( new Location( $entity->getLocationName() ));
// have to tell Doctrine that the Location has been updated
$cmf = $args->getEntityManager()->getMetadataFactory();
$class = $cmf->getMetadataFor(get_class($entity));
$args->getEntityManager()->getUnitOfWork()->computeChangeSet($class, $entity); // don't use recomputeSingleEntityChangeSet here - that doesn't care about relationships
}
}
}
}