如何将原则ORM默认跟踪策略更改为延迟显式



我正在我的最新项目中使用带有symfony的Doctrine ORM。我需要我的学说默认使用延迟显式跟踪策略 - 我需要控制保存的内容和时间。

我可以在其注释中更改每个实体的学说跟踪策略

/**
* @ORMChangeTrackingPolicy("DEFERRED_EXPLICIT")
*/

但我想将此跟踪策略设为所有实体的默认跟踪策略。我不想仅仅因为这个而创建一个通用的父实体。有没有办法为整个项目设置此跟踪策略默认值?

关于学说跟踪政策。

适合您时间的坦克

有一个

DoctrineORMEvents::loadClassMetadata事件,你可以挂接到并创建一个侦听器,以覆盖实体元数据中的策略。

侦听器是在从注释/yml/xml 加载元数据之后调用的,然后再将它们保存在缓存中,因此它应该非常有效。

    事件
  • :生命周期事件
  • 事件
  • :装入类元数据事件
  • Symfony:如何注册事件侦听器和订阅者

下面是一些工作代码:

class DoctrineTrackingPolicySubscriber implements EventSubscriber
{
    public function getSubscribedEvents()
    {
        return [
            Events::loadClassMetadata
        ];
    }
    public function loadClassMetadata(LoadClassMetadataEventArgs $args)
    {
        $classMetadata = $args->getClassMetadata();
        $classMetadata->setChangeTrackingPolicy(
            ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT
        );
    }
}

然后在services.yamlservices.yml

AppEventSubscriberDoctrineTrackingPolicySubscriber:
    tags:
        - { name: doctrine.event_subscriber, connection: default }

对于Symfony版本<3.3,指定一个class是必要的,较新的版本隐式假定服务名称是FQCN。

您可以通过定义自己的工厂来构造DoctrineORMMappingClassMetadata,将默认更改跟踪策略从延迟隐式更改为延迟显式

此方法仍允许您的配置指定其中之一,否则仅影响您的配置未另行指定的位置。

<?php
class MyClassMetadataFactory extends DoctrineORMMappingClassMetadataFactory
{
    /**
     * {@inheritDoc}
     */
    protected function newClassMetadataInstance($className)
    {
        $classMetadata = parent::newClassMetadataInstance($className);
        // Change the default Change Tracking Policy to Deferred Explicit.
        $classMetadata->setChangeTrackingPolicy(
            DoctrineORMMappingClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT
        );
        return $classMetadata;
    }
}
$xmlMetadataConfig = DoctrineORMToolsSetup::createXMLMetadataConfiguration([__DIR__ . '/config']);
// Set your class to be the factory for ClassMetadata.
$xmlMetadataConfig->setClassMetadataFactoryName(MyClassMetadataFactory::class);
$em = DoctrineORMEntityManager::create(
    ['pdo' => $pdo],
    $xmlMetadataConfig
);

该战略的关键要素如下。

  • 重写DoctrineORMMappingClassMetadataFactory::newClassMetadataInstance()以更改构造的 DoctrineORMMappingClassMetadata 实例的属性。
  • 将类设置为要在元数据驱动程序配置中使用的工厂。

我当前的解决方案比在整个项目范围内更改跟踪策略更烦人 - 我必须始终将所有更改的实体传递给 EntityManager->flush($entity=null)。换句话说 - 我必须防止调用没有参数的刷新方法。

相关内容

  • 没有找到相关文章

最新更新