使用事件侦听器创建preUpdate或preFlush事件 [英] Creating preUpdate or preFlush event with Event Listener
问题描述
测试:我将退出
在 preFlush()
,看看它是否全部被调用。结果是: 1 所以 foreach()
永远不会运行!它是一个空数组。我还测试了preUpdate()和所有的行,但是没有插入数据。
public function preFlush(PreFlushEventArgs $ args )
{
$ em = $ args-> getEntityManager();
$ uow = $ em-> getUnitOfWork();
echo'1';
foreach($ uow-> getScheduledEntityUpdates()as $ entity){
echo'2';
if($ entity instanceof User){
echo'3';
}
}
exit;
}
我在阅读了文档。
service.yml
services:
entity.event_listener.user:
class:Site\FrontBundle \EventListener\Entity\UserListener
标签:
- {name:doctrine.event_listener,event:preUpdate}
- {name:doctrine.event_listener,event:onFlush}
- {name:doctrine.event_listener,event:preFlush}
Working onFlush()示例:
class UserListener
{
public function onFlush(OnFlushEventArgs $ args)
{
$ em = $ args-> getEntityManager();
$ uow = $ em-> getUnitOfWork();
foreach($ uow-> getScheduledEntityUpdates()as $ entity){
if($ entity instanceof User){
$ userLog = new UserLog();
$ userLog-> setDescription($ entity-> getId()。'正在更新。
$ em-> persist($ userLog);
//代替$ em-> flush()cos我们已经在flush进程
$ userLogMetadata = $ em-> getClassMetadata(get_class($ userLog));
$ uow-> computeChangeSet($ userLogMetadata,$ userLog);
}
}
}
}
strong>不工作preFlush()示例:
class UserListener
{
public function preFlush(PreFlushEventArgs $ args)
{
$ em = $ args-> getEntityManager();
$ uow = $ em-> getUnitOfWork();
foreach($ uow-> getScheduledEntityUpdates()as $ entity){
if($ entity instanceof User){
$ userLog = new UserLog();
$ userLog-> setDescription($ entity-> getId()。'正在更新。
$ em-> persist($ userLog);
//代替$ em-> flush()cos我们已经在flush进程
$ userLogMetadata = $ em-> getClassMetadata(get_class($ userLog));
$ uow-> computeChangeSet($ userLogMetadata,$ userLog);
}
}
}
}
strong>不工作preUpdate()示例
class UserListener
{
public function preUpdate (LifecycleEventArgs $ args)
{
$ entity = $ args-> getEntity();
$ em = $ args-> getEntityManager();
$ uow = $ em-> getUnitOfWork();
if($ entity instanceof User){
$ userLog = new UserLog();
$ userLog-> setDescription($ entity-> getId()。')已更新。
$ em = $ args-> getEntityManager();
$ em-> persist($ userLog);
$ userLogMetadata = $ em-> getClassMetadata(get_class($ userLog));
$ uow-> computeChangeSet($ userLogMetadata,$ userLog);
}
}
}
解决方案:
诀窍是,在 preUpdate()
在 postFlush()
事件中。
注意: 虽然这可能不是最好的解决方案,但它可以解决这个问题,但是可以使用事件订阅者或简单的 onFlush()
- > $ uow - > getScheduledEntityUpdates()
在事件监听器中。
Service.yml
服务:
entity.event_listener.user_update:
class:Site\FrontBundle\EventListener\Entity\\ \\ UserUpdateListener
标签:
- {name:doctrine.event_listener,event:preUpdate}
- {name:doctrine.event_listener,event:postFlush}
事件监听器
code><?php
命名空间Site\FrontBundle\EventListener\Entity;
使用Doctrine\ORM\Event\LifecycleEventArgs;
使用Doctrine\ORM\Event\PostFlushEventArgs;
使用Site\FrontBundle\Entity\User;
使用Site\FrontBundle\Entity\UserLog;
class UserUpdateListener
{
private $ log = array();
public function preUpdate(LifecycleEventArgs $ args)
{
$ entity = $ args-> getEntity();
//虚假检查是强制的,否则重复出现
if(($ entity instanceof User)=== false){
$ userLog = new UserLog();
$ userLog-> setDescription($ entity-> getId()。'正在更新。
$ this-> log [] = $ userLog;
}
}
public function postFlush(PostFlushEventArgs $ args)
{
if(!empty($ this-> log)){
$ em = $ args-> getEntityManager();
foreach($ this-> log as $ log){
$ em-> persist($ log);
}
$ em-> flush();
}
}
}
I have a onFlush() event which works fine but what I need to do is to turn that into preFlush() or preUpdate() both acceptable. I did preFlush() but for some reason it doesn't do anything. Not even an error. What am I missing?
TEST: I placed exit
in preFlush()
to see if it is being called at all or not. Outcome is: 1 so foreach()
is never run! It is an empty array. I also tested preUpdate() and all the lines in that get runed but no data inserted.
public function preFlush(PreFlushEventArgs $args)
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
echo '1';
foreach ($uow->getScheduledEntityUpdates() as $entity) {
echo '2';
if ($entity instanceof User) {
echo '3';
}
}
exit;
}
I created them after reading the documentation.
service.yml
services:
entity.event_listener.user:
class: Site\FrontBundle\EventListener\Entity\UserListener
tags:
- { name: doctrine.event_listener, event: preUpdate }
- { name: doctrine.event_listener, event: onFlush }
- { name: doctrine.event_listener, event: preFlush }
Working onFlush() example:
class UserListener
{
public function onFlush(OnFlushEventArgs $args)
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityUpdates() as $entity) {
if ($entity instanceof User) {
$userLog = new UserLog();
$userLog->setDescription($entity->getId() . ' being updated.');
$em->persist($userLog);
// Instead of $em->flush() cos we're already in flush process
$userLogMetadata = $em->getClassMetadata(get_class($userLog));
$uow->computeChangeSet($userLogMetadata, $userLog);
}
}
}
}
Not working preFlush() example:
class UserListener
{
public function preFlush(PreFlushEventArgs $args)
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityUpdates() as $entity) {
if ($entity instanceof User) {
$userLog = new UserLog();
$userLog->setDescription($entity->getId() . ' being updated.');
$em->persist($userLog);
// Instead of $em->flush() cos we're already in flush process
$userLogMetadata = $em->getClassMetadata(get_class($userLog));
$uow->computeChangeSet($userLogMetadata, $userLog);
}
}
}
}
Not working preUpdate() example
class UserListener
{
public function preUpdate(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
if ($entity instanceof User) {
$userLog = new UserLog();
$userLog->setDescription($entity->getId() . ') been updated.');
$em = $args->getEntityManager();
$em->persist($userLog);
$userLogMetadata = $em->getClassMetadata(get_class($userLog));
$uow->computeChangeSet($userLogMetadata, $userLog);
}
}
}
SOLUTION:
The trick is, persisting after preUpdate()
within postFlush()
event.
Note: Although this might not be the best solution, it answers the question however it could be done with an Event Subscriber or simple onFlush()
-> $uow->getScheduledEntityUpdates()
in an Event Listener.
Service.yml
services:
entity.event_listener.user_update:
class: Site\FrontBundle\EventListener\Entity\UserUpdateListener
tags:
- { name: doctrine.event_listener, event: preUpdate }
- { name: doctrine.event_listener, event: postFlush }
Event Listener
<?php
namespace Site\FrontBundle\EventListener\Entity;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PostFlushEventArgs;
use Site\FrontBundle\Entity\User;
use Site\FrontBundle\Entity\UserLog;
class UserUpdateListener
{
private $log = array();
public function preUpdate(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
// False check is compulsory otherwise duplication occurs
if (($entity instanceof User) === false) {
$userLog = new UserLog();
$userLog->setDescription($entity->getId() . ' being updated.');
$this->log[] = $userLog;
}
}
public function postFlush(PostFlushEventArgs $args)
{
if (! empty($this->log)) {
$em = $args->getEntityManager();
foreach ($this->log as $log) {
$em->persist($log);
}
$em->flush();
}
}
}
这篇关于使用事件侦听器创建preUpdate或preFlush事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!