我有一个实体主题:
/**
*
* @ORM\Table()
* @ORM\HasLifecycleCallbacks()
*/
class Subject
{
//... Some fields
/**
* @ORM\OneToMany(targetEntity="Subject", mappedBy="mark", cascade={"persist", "remove"})
*/
private $subjects;
private function calculateMarks()
{
//... Do something
// return array with (abilities => marks);
}
/**
* @ORM\PrePersist()
*/
public function prePersist(){
$now = new \DateTime();
$this->setCreatedAt( $now );
$this->setModifiedAt( $now );
}
/**
* @ORM\PreUpdate()
*/
public function preUpdate(){
$this->setModifiedAt( new \DateTime() );
$this->setUpdated(true);
}
/**
* @ORM\PreFlush()
*/
public function preFlush(){
$marks = calculateMarks();
foreach($marks as $ability => $score){
$mark = new Mark();
$mark->setSubject( $this );
$this->addMark( $score );
$mark->setAbility( $ability );
}
}
}
和Mark类:
class Mark{
// Many fields
/**
* @ORM\ManyToOne(targetEntity="Subject", inversedBy="subjects")
* @ORM\JoinColumn(name="subject_id", referencedColumnName="id")
*/
private $subject;
}
我的问题是我计算并在preFlush事件中创建了Marks(这样做是因为在官方文档中说的是关于preUpdate事件:“在此事件中永远不允许更新实体的关联,因为Doctrine不能保证在刷新操作的这一点上正确处理参照完整性“)。当我保存一个主题时,一切正常,但是当我在Web服务中同时保存多个主题时,一些标记会多次存储在数据库中。
以下网络服务行动:
public function setSubjects(Request $request)
{
//... Do something
$subjects = $request["Subjects"];
foreach($subjects as $s){
$em = $this->getDoctrine()->getManager();
//... Do something
$em->persist($s);
$em->flush();
}
return new JsonResponse($response);
}
有没有人知道如何在preFlush事件中避免这种行为?
提前致谢。
答案 0 :(得分:0)
我总是尽量避免使用LifecycleCallbacks
,除非它很简单,而且我只是在同一个实体中更改属性。
解决你的问题我会在实体中创建一个函数calculateMarks()
并调整我的循环就像
$em = $this->getDoctrine()->getManager();
foreach($subjects as $s){
//... Do something
$s->calculateMarks();
$em->persist($s);
}
$em->flush();
注意
避免$em = $this->getDoctrine()->getManager();
&循环中的$em->flush();