Symfony doctrine多对多完整性约束违规:1062重复条目

时间:2018-01-23 20:26:18

标签: php symfony doctrine-orm

我有一个具有manyToMany('Self-Referencing')关系的实体User。

/**
     * @Serializer\Expose()
     * @ORM\ManyToMany(targetEntity="User")
     * @ORM\JoinTable(name="user_referent",
     *  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *  inverseJoinColumns={@ORM\JoinColumn(name="coach_id", referencedColumnName="id")}
     * )
     * @ORM\JoinColumn(nullable=true)
     * @Assert\Valid
     *
     */
    private $coaches;

在我尝试创建重复条目的测试期间,我从sql(SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry.)获得了正确的消息 但我想在冲洗之前抓住副本。所以我在add函数中添加了一个if语句。

public function addCoach(User $coach)
    {
        if ($this->coaches->contains($coach)) {
            return;
        }
        $this->coaches[] = $coach;

    }

但似乎在使用表单时,不会调用addCoach函数。当我转储它时,没有转储任何值。 我在@Assert\Valid上尝试了@Unique@Table或约束......但没有任何效果。 有没有办法设置一个约束多对多的关系抛出一个消息,就像在一个实体的任何其他项目上一样?

1 个答案:

答案 0 :(得分:1)

只有当您明确调用该方法以在持久化之前在用户实体上添加coach时,才会调用addCoach方法。它不会被隐式调用。

您可以在User实体中使用onPrePersist方法,这是每次尝试将实体刷新到DB时检查重复项的隐式方法。

使用以下内容更新您的用户实体的doctrine orm文件。

<lifecycle-callbacks>
   <lifecycle-callback type="prePersist" method="prePersist" />
</lifecycle-callbacks>

然后使用以下内容更新用户实体文件。

    /**
     * @PrePersist
     */
    public function onPrePersist()
    {
        // remove duplicates from coaches array.

        $coachKeys[] = array();
        foreach($this->coaches as $key => $coach) {
            if(!in_array($coach->getUserId(), $coachKeys) {
                $coachKeys[] = $key;
            } else {
               $this->removeCoach($this->coach); // unset($this->coache[$key]);
            }     
        }           
    }

这将确保在刷新之前删除重复的条目。