我有一个具有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
或约束......但没有任何效果。
有没有办法设置一个约束多对多的关系抛出一个消息,就像在一个实体的任何其他项目上一样?
答案 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]);
}
}
}
这将确保在刷新之前删除重复的条目。