Doctrine 2 a EntityListener neproběhne v transakci
- Jiří Nápravník
- Člen | 710
Používám Doctrine a EntityListenery. Konkrétně tady dávám příklad na to, že po přidání či smazání položky chci updatovat počet odpovědí, na což jsou ideální EntityListenery. Jenže problém je, že když volám v tom EntityListeneru nějakou query s update, či pod. Tak se nepovede v transakci když zavolám $em->flush() ale po nebo před (podle toho jestli je to preEvent nebo postEvent) Jediným řešením je, když volám $em->remove(), tak to obalit do $em->transactional(), pak se proveodu pre i post eventy jak chci, ale není nějaké lepší řešní? Tohle je hodně blbý…
/**
* @ORM\Entity
* @ORM\EntityListeners({"DiscussionModule\Model\Entities\Listeners\DiscussionConversationListener"})
*/
class DiscussionConversation extends BaseEntity
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type = "integer")
*/
protected $id;
/**
* @ORM\Column(type = "text")
*/
protected $text;
/**
* @ORM\Column(type = "integer")
*/
protected $answersCount;
}
class DiscussionConversationListener
{
/**
* @ORM\PostPersist
* @ORM\PostRemove
*/
public function recountAnswersCount(DiscussionConversation $conversation, LifecycleEventArgs $event){
$count = $event->getEntityManager()->createQuery('SELECT COUNT(c2.id) FROM ' . DiscussionConversation::getClassName() . ' c2 JOIN c2.user u '
. 'WHERE c2.topic = :topic AND c2.mainTopic = FALSE')
->setParameter('topic', $conversation->getTopic())
->getSingleScalarResult();
$qb = $event->getEntityManager()->createQueryBuilder();
$qb->update(DiscussionConversation::getClassName(), 'c')
->set('c.answersCount', $count)
->where('c.topic = :topic AND c.mainTopic = TRUE')
->setParameter('topic', $conversation->getTopic())
->getQuery()
->execute();
}
}
- maryo
- Člen | 15
https://github.com/…itOfWork.php#…
Tady začíná transakce.
Takže to můžeš zkusit při onFlush celý obalit ještě do jedný přímo
z toho listeneru, tj. zavolat
$entityManager->beginTransaction();
.
a potom při postFlush transakci potvrdit pomocí
$entityManager->commit();
.
Vzhledem k tomu, že už nevoláš další flush (resp. další UnitOfWork::commit), tak by to (pokud mi něco neuniklo) teoreticky mělo jít.
Editoval maryo (19. 11. 2014 1:33)