对不起标题,我不知道怎么说。
我有两个实体:在管上有一个OneToMany关系的Strain,以及一个cascade = {“persist”,“remove”}属性。 对于两次实体,我使用PrePersist回调动态定义其名称。但是,它只适用于Tube实体,在Strain实体上我遇到了问题,因为它的名字是在第一个管名上定义的。我认为PrePersist用于Tubes之前的Strain。然后,如果Tubes没有名称,Strain的名称为空。
如果我在控制器中做一个foreach,在坚持应变之前逐个坚持每个管,它可以正常工作。但我真的不喜欢它。我们可以在某处配置它,比如PrePersist的优先顺序吗?
我的实体:
管
class Tube
{
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Strain", inversedBy="tubes")
*/
private $gmoStrain;
...
// SETTERS & GETTERS
public function setStrain(Strain $strain)
{
$this->strain = $strain;
return $this;
}
public function getStrain()
{
return $this->strain;
}
...
//LifecycleCallback
/**
* Before persist.
*
* @ORM\PrePersist()
*/
public function prePersist()
{
// Give a name to the tube
// The name is composed like this:
// ProjectPrefix_BoxLetter_xxxType
// ProjectPrefix (The prefix of the first Tube)
$projectPrefix = $this->getBox()->getProject()->getPrefix();
// BoxLetter (idem, the first tube)
$boxLetter = $this->getBox()->getBoxLetter();
// In array the first cell is 0, in real box, it's 1
$cell = $this->cell + 1;
// Adapt the boxCell like: 1 => 001, 10 => 010, 100 => 100, never more than 999
if ($cell < 10) {
$boxCell = '00'.$cell;
} elseif ($cell > 99) {
$boxCell = $cell;
} else {
$boxCell = '0'.$cell;
}
// Type Letter
$lastLetter = $this->getStrain()->getType()->getLetter();
// Generate the tube name
$this->name = $projectPrefix.'_'.$boxLetter.$boxCell.$lastLetter;
}
}
毒株:
class Strain
{
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Tube", mappedBy="strain", cascade={"persist", "remove"})
*/
private $tubes;
...
//SETTERS & GETTERS
public function addTube(Tube $tube)
{
if (!$this->tubes->contains($tube)) {
$tube->setGmoStrain($this);
$this->tubes->add($tube);
}
}
public function removeTube(Tube $tube)
{
if ($this->tubes->contains($tube)) {
$this->tubes->removeElement($tube);
}
}
public function getTubes()
{
return $this->tubes;
}
...
//LifecycleCallback
/**
* Before persist.
*
* @ORM\PrePersist()
*/
public function postPersist()
{
// The automatic name of the strain is the name of the first tube
// when the strain is registred the first time
$this->systematicName = $this->getTubes()->first()->getName();
}
}
答案 0 :(得分:0)
如果您需要设置prePersist
事件的优先级,可以使用Event Listeners and Subscribers服务代替@ORM\PrePersist
注释来完成此操作。
首先,为prePresist
事件创建Tube监听器类:
// src/AppBundle/EventListener/TubeListener.php
namespace AppBundle\EventListener;
use Doctrine\ORM\Event\LifecycleEventArgs;
use AppBundle\Entity\Tube;
class TubeListener
{
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!$entity instanceof Tube) {
return;
}
$em = $args->getEntityManager();
// do something with the Tube
}
}
接下来,注册监听器,默认情况下,如果没有提供优先级标签属性,那么它的分区为0
:
services:
app.event_listener.tube:
class: AppBundle\EventListener\TubeListener
tags:
- { name: doctrine.event_listener, event: prePersist }
稍后,为同一Strain
事件创建第二个prePresist
侦听器类:
// src/AppBundle/EventListener/StrainListener.php
namespace AppBundle\EventListener;
use Doctrine\ORM\Event\LifecycleEventArgs;
use AppBundle\Entity\Strain;
class StrainListener
{
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!$entity instanceof Strain) {
return;
}
$em = $args->getEntityManager();
// do something with the Strain (at this moment pre-persist Tube already called)
}
}
现在,注册此侦听器的优先级低于TubeListener
:
services:
app.event_listener.strain:
class: AppBundle\EventListener\StrainListener
tags:
- { name: doctrine.event_listener, event: prePersist, priority: -5 }
从而确保第一个prePersist
事件(具有优先级0
)已在第二个事件之前执行(优先级-5
)。这也可以使用订阅者进行存档。