我希望每次保存一個新的Distance
實體(從Place_A到Place_B),反向距離(從Place_B到Place_A)gets inserted too into the DB。無限循環在Doctrine事件監聽器試圖保存附加實體時
我的問題是下面的聽衆無限循環(因此計數器):
class Listener
{
public $count;
public function prePersist(LifecycleEventArgs $eventArgs)
{
if ($this->count > 5) {
die();
}
$entity = $eventArgs->getEntity();
if ($entity instanceof Distance) {
// $this->created = microtime(true) in Distance's constructor
echo 'Entity created at ' . $entity->created;
if ($entity->isReverse) {
echo " is reverse\n";
} else {
echo " is not reverse\n";
$this->count++;
$reverse = new Distance();
$reverse->setOrigin($entity->getDestination());
$reverse->setDestination($entity->getOrigin());
$reverse->set($entity->getMiles());
$reverse->isReverse = true;
$em = $eventArgs->getEntityManager();
$em->persist($reverse);
$em->flush();
}
}
}
}
輸出:
Entity created at 1433168310.8787 is not reverse
Entity created at 1433168310.9073 is reverse
Entity created at 1433168310.8787 is not reverse
Entity created at 1433168310.9078 is reverse
Entity created at 1433168310.8787 is not reverse
Entity created at 1433168310.908 is reverse
Entity created at 1433168310.8787 is not reverse
Entity created at 1433168310.9084 is reverse
Entity created at 1433168310.8787 is not reverse
Entity created at 1433168310.9087 is reverse
Entity created at 1433168310.8787 is not reverse
這就像原來的實體(創建時間8787結束)的持續無限次數。
以防萬一,如果我刪除調用$em->flush
,我正確地得到下面的輸出:
Entity created at 1433167824.2552 is not reverse
Entity created at 1433167824.2947 is reverse
但隨後一個異常說,沒有參數綁定到插入查詢。這是由Symfony的分析器證實:
INSERT INTO Distance (
miles, origin_id, destination_id
)
VALUES
(?, ?, ?)
Parameters: { }
我想了解爲什麼我的聽衆不能按我的預期工作,以及如何解決它。
按照要求,這裏的一些更多的代碼。一切都來自於Place
表格,除了輸入地名,我可以添加/刪除/編輯其他Place
的距離集合。
// PlaceController::updateAction
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('MyBundle:Place')->find($id);
if (! $entity) {
throw $this->createNotFoundException('Unable to find Place entity.');
}
$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createForm(new PlaceType(), $entity, array(
'action' => $this->generateUrl('update_place', array('id' => $entity->getId())),
'method' => 'PUT'
));
$editForm->add('submit', 'submit', array('label' => 'panel.button.save'));
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return array(
'entity' => $entity,
'form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
);
}
// PlaceType::buildForm
public function buildForm(FormBuilderInterface $builder, array $options)
{
$Place = $builder->getData();
$builder
->add(
'name',
'text',
[
'label' => 'object.place.name'
]
)
->add(
'distancesTo',
'collection',
[
'label' => 'object.place.distance.plural',
'type' => new DistanceType(),
'by_reference' => false,
'allow_add' => true,
'allow_delete' => true,
'options' => [
'required' => false,
'origin' => $Place->getId() ? $Place : null
]
]
);
}
那麼首先你不應該有一個調用''em-> flush()'無論如何,因爲它是一個糟糕的形式在prePersist塊中刷新,因爲實體管理器可能會刷新原始位置被堅持。 – DIMMSum
你可以添加原始實體持續存在的代碼嗎? – DIMMSum
@Decave堅持原始距離實體的代碼不是我的。如我的編輯中所解釋的,當持久化父級Place實體(關聯中的「cascade:{」persist「})時會自動發生。 – marcv