Doctrine中的一对一关系仅更新一个字段 - 完整性约束违规:1062重复条目

时间:2015-10-22 13:26:37

标签: php mysql symfony orm doctrine-orm

这是我之前发布的帖子Relations while updating entity in Symfony2 - one-to-one and one-to-many doesn't work

的后续内容

虽然我已经成功解决了One-to-Many的问题,虽然通过Controller中的一些脏修复,同样不适用于One-to-One,我得到以下错误:     SQLSTATE [23000]:完整性约束违规:1062密钥'UNIQ_3BAE0AA753C674EE'重复输入'16'

守则:

    Class Offer {
/**
 * @var Event
 *
 * @ORM\OneToOne(targetEntity="Event", inversedBy="offer")
 * @ORM\JoinColumn(name="event_id", referencedColumnName="id")
 */
private $event;
}

    Class Event {
/**
 * @var Offer
 *
 * @ORM\OneToOne(targetEntity="Offer", mappedBy="event")
 * @ORM\JoinColumn(name="offer_id", referencedColumnName="id", onDelete="SET NULL")
 */
private $offer;
}

另外,在最后一篇文章中,我建议我在setEvent上添加以下代码(恰好是“$ event-> setOffer($ this);”part:

/**
 * Set event
 *
 * @param \AppBundle\Entity\Event $event
 * @return Offer
 */
public function setEvent(\AppBundle\Entity\Event $event)
{
    $this->event = $event;
    $event->setOffer($this);

    return $this;
}

更新后,它只用正确的数据填充Offer表中的event_id,或者在修改代码后我得到有关重复条目的错误SQLSTATE [23000]:完整性约束违规:1062重复条目'16'用于密钥'UNIQ_3BAE0AA753C674EE'

知道我做错了什么吗?我很感激任何反馈。

更新&解决方案(在OfferController中添加到updateAction的代码):

$oldEvent = $em->getRepository('AppBundle:Event')->findOneBy(array("offer"=>$entity));
 if ($oldEvent != NULL) {
 $oldEvent->removeOffer(); 
 $em->persist($oldEvent); 
 } $newEvent = $entity->getEvent(); 

 $entity->setEvent($newEvent);

不是一种简洁的方式,而是一种快速修复,但工作正常,但仍然感兴趣的是它在ORM Doctrine方式中不能用于开箱即用。

1 个答案:

答案 0 :(得分:1)

In the documentation你可以读到:

  

Doctrine只会检查协会的拥有方是否有变更。

here详细说明:

  

要完全理解这一点,请记住在对象世界中如何维护双向关联。关联的每一侧有2个引用,这两个引用都代表相同的关联,但可以彼此独立地改变。当然,在正确的应用程序中,双向关联的语义由应用程序开发人员正确维护(这是他的职责)。 Doctrine需要知道这两个内存引用中的哪一个应该是持久化的,哪些不是。这就是拥有/反向概念主要用于。

您的setEvent方法完全按照预期的方式执行。它还负责关系的反面。
但这也意味着您必须从拥有方管理您的实体。 Offer是该关系的拥有方,因此我建议您在$offer而不是$event上继续调用。

$offer->setEvent($event);
$em->persist($offer);