Doctrine 我应该使用什么事件来检测实体再次被持久化但没有被更改?
我想在更新实体时触发一个事件,即使数据没有更改。那么,我应该使用什么事件 提醒:我想访问实体数据,因此我不能使用Doctrine 我应该使用什么事件来检测实体再次被持久化但没有被更改?,doctrine,symfony,Doctrine,Symfony,我想在更新实体时触发一个事件,即使数据没有更改。那么,我应该使用什么事件 提醒:我想访问实体数据,因此我不能使用onFlush。此外,由于未更改实体数据,因此不会触发preUpate或positionpdate 您可以在service manager中集中实体的存储。 在这种情况下,经理试图派遣一个一般事件 use Symfony\Component\EventDispatcher\GenericEvent; ... ... public function persistAndFlush
onFlush
。此外,由于未更改实体数据,因此不会触发preUpate
或positionpdate
您可以在service manager中集中实体的存储。 在这种情况下,经理试图派遣一个一般事件
use Symfony\Component\EventDispatcher\GenericEvent;
...
...
public function persistAndFlush($entity)
{
$this->em->persist($entity);
$this->em->flush();
//dispatch an event
$event = new GenericEvent($entity, array('course_history' => 1));
$this->dispatcher->dispatch(YourClassEvents::UPDATE_ENTITY, $event);
}
然后,您可以创建一个listner来侦听此一般事件
编辑
更多详细信息
假设我们有实体产品
- 创建服务管理器
您可以在service manager中集中实体的数据。 在这种情况下,经理试图派遣一个一般事件
use Symfony\Component\EventDispatcher\GenericEvent;
...
...
public function persistAndFlush($entity)
{
$this->em->persist($entity);
$this->em->flush();
//dispatch an event
$event = new GenericEvent($entity, array('course_history' => 1));
$this->dispatcher->dispatch(YourClassEvents::UPDATE_ENTITY, $event);
}
然后,您可以创建一个listner来侦听此一般事件
编辑
更多详细信息
假设我们有实体产品
- 创建服务管理器
我看到了问题所在。您希望在更新后访问实体,但该实体不是真正的更新。显然,您在这里使用了DQL查询,正如您正确提到的。问题是,条令并不真正知道对象已被更改-查询可能有点复杂,因此对象标识符可能会被隐藏。甚至不知道(在MySQL的情况下) 一些RDBMs有
RETURNING
子句,允许您查看更新结果,但它不是DB抽象的,因此无法从DQL开箱即用访问
您可以使用本机SQL查询或执行其他技巧来获取更新的行
如果查询不是性能关键的,我宁愿建议使用一些软件(php端)进行简单的处理
如果是,我认为这是不可能的。如果您了解用例的更多细节,可以讨论解决方法
也就是说,您可以使用迭代的方法对EM中缓存的所有实体进行迭代,并检查vesrion是否已更改。我看到了这里的问题。您希望在更新后访问实体,但该实体不是真正的更新。显然,您在这里使用了DQL查询,正如您正确提到的。问题是,条令并不真正知道对象已被更改-查询可能有点复杂,因此对象标识符可能会被隐藏。甚至不知道(在MySQL的情况下) 一些RDBMs有
RETURNING
子句,允许您查看更新结果,但它不是DB抽象的,因此无法从DQL开箱即用访问
您可以使用本机SQL查询或执行其他技巧来获取更新的行
如果查询不是性能关键的,我宁愿建议使用一些软件(php端)进行简单的处理
如果是,我认为这是不可能的。如果您了解用例的更多细节,可以讨论解决方法
也就是说,您可以使用iterate对EM中缓存的所有实体进行迭代,并检查vesrion是否已更改
<service id="yourdomain.product_manager" class="Domain\YourBundle\Service\ProductManager">
<argument type="service" id="doctrine.orm.entity_manager"/>
<argument type="service" id="event_dispatcher"/>
</service>
namespace Domain\YourBundle\Manager;
use Doctrine\ORM\EntityManager;
use Domain\YourBundle\Entity\Product;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
class ProductManager
{
/**
* @var EntityManager
*/
protected $em;
/**
* @var EventDispatcherInterface
*/
protected $dispatcher;
/**
* @param EntityManager $em
*/
public function __construct(EntityManager $em, EventDispatcherInterface $dispatcher)
{
$this->em = $em;
$this->dispatcher = $dispatcher;
}
public function persistAndFlush($product)
{
$this->em->persist($product);
$this->em->flush();
//The entity is updated then dispatch an event
$event = new GenericEvent($product, array('product_name' => 1));
$this->dispatcher->dispatch('product', $event);
}
}
<service id="yourdomain.event.update_product" class="Domain\YourBundle\EventListener\UpdateProductListener">
<argument type="service" id="logger"/>
<tag name="kernel.event_listener" event="product" method="onUpdateProduct"/>
</service>
namespace Domain\YourBundle\EventListener;
use Symfony\Component\EventDispatcher\GenericEvent;
use Domain\YourBundle\Entity\Product;
use Psr\Log\LoggerInterface;
class UpdateProductListener
{
private $logger;
/**
* @param LoggerInterface $logger
*/
public function __construct(LoggerInterface $logger) {
$this->logger = $logger;
}
/**
* Listen the generic event dispatched when the product name is updated
*
* @param GenericEvent $event
*
* @throws RuntimeException
* @throws \ErrorException
*/
public function onUpdateProduct(GenericEvent $event)
{
if ($event->getSubject() instanceof Product) {
$product = $event->getSubject();
if ($event->hasArgument('product_name') && $event->getArgument('product_name') == 1) {
/*
Make your logic (send mail, add log, notification....)
*/
$this->logger->notice('UpdateProductListener : event update product is occured');
} else {
$this->logger->notice('UpdateProductListener : event other than update product is occured.');
}
}
}
}