沃梦达 / 编程问答 / php问题 / 正文

如何判断当前交易是否会改变 Doctrine 2 的任何实体?

How can I tell if the current transaction will change any entities with Doctrine 2?(如何判断当前交易是否会改变 Doctrine 2 的任何实体?)

本文介绍了如何判断当前交易是否会改变 Doctrine 2 的任何实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Doctrine 来保存用户数据,并且我想要一个 last modified 字段.这是用户按下 Save 后我希望如何保存表单的伪代码:

I'm using Doctrine to save user data and I want to have a last modification field. Here is the pseudo-code for how I would like to save the form once the user presses Save:

  • 开始交易
  • 做很多事情,可能是查询数据库,也可能不是
  • 如果此交易有任何改变
    • 修改 last updated 字段

    有问题的部分是这个交易是否会改变任何东西.Doctrine 可以给我这样的信息吗?

    The problematic part is if anything will be changed by this transaction. Can Doctrine give me such information?

    如何判断当前事务中的实体是否发生了变化?

    How can I tell if entities have changed in the current transaction?

    编辑

    为了解决问题,我试图修改名为 User 的实体中名为 lastUpdated 的字段,如果有任何实体(包括但不限于 User) 将在当前事务提交后更改.换句话说,如果我开始交易并修改名为 Garage 的实体的名为 nbCars 的字段,我希望更新的 lastUpdated 字段User 实体,即使该实体尚未修改.

    Just to clear things up, I'm trying to modify a field called lastUpdated in an entity called User if any entity (including but not limited to User) will be changed once the currect transaction is commited. In other words, if I start a transaction and modify the field called nbCars of an entity called Garage, I wish to update the lastUpdated field of the User entity even though that entity hasn't been modified.

    推荐答案

    这是一个必要的回复,旨在更正@ColinMorelli 发布的内容(因为不允许在生命周期事件侦听器中刷新 - 是的,文档中有一个位置否则说,但我们会摆脱它,所以请不要这样做!).

    This is a necessary reply that aims at correcting what @ColinMorelli posted (since flushing within an lifecycle event listener is disallowed - yes, there's one location in the docs that says otherwise, but we'll get rid of that, so please don't do it!).

    你可以简单地听onFlush 带有如下监听器:

    You can simply listen to onFlush with a listener like following:

    use DoctrineCommonEventSubscriber;
    use DoctrineORMEventOnFlushEventArgs;
    use DoctrineORMEvents;
    
    class UpdateUserEventSubscriber implements EventSubscriber
    {
        protected $user;
    
        public function __construct(User $user)
        {
            // assuming the user is managed here
            $this->user = $user;
        }
    
        public function onFlush(OnFlushEventArgs $args)
        {
            $em  = $args->getEntityManager();
            $uow = $em->getUnitOfWork();
    
            // before you ask, `(bool) array()` with empty array is `false`
            if (
                $uow->getScheduledEntityInsertions()
                || $uow->getScheduledEntityUpdates()
                || $uow->getScheduledEntityDeletions()
                || $uow->getScheduledCollectionUpdates()
                || $uow->getScheduledCollectionDeletions()
            ) {
                // update the user here
                $this->user->setLastModifiedDate(new DateTime());
                $uow->recomputeSingleEntityChangeSet(
                    $em->getClassMetadata(get_class($this->user)), 
                    $this->user
                );
            }
        }
    
        public function getSubscribedEvents()
        {
            return array(Events::onFlush);
        }
    }
    

    仅当 UnitOfWork 包含要提交到数据库的更改时,这才会将更改应用于配置的 User 对象(工作单元实际上是您可能的定义为应用级状态事务).

    This will apply the change to the configured User object only if the UnitOfWork contains changes to be committed to the DB (an unit of work is actually what you could probably define as an application level state transaction).

    您可以随时通过调用在 ORM 中注册此订阅者

    You can register this subscriber with the ORM at any time by calling

    $user         = $entityManager->find('User', 123);
    $eventManager = $entityManager->getEventManager();
    $subscriber   = new UpdateUserEventSubscriber($user);
    
    $eventManager->addEventSubscriber($subscriber);
    

    这篇关于如何判断当前交易是否会改变 Doctrine 2 的任何实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:如何判断当前交易是否会改变 Doctrine 2 的任何实体?

基础教程推荐