【问题标题】:resolve target entities compiler pass解析目标实体编译器传递
【发布时间】:2016-01-16 18:44:53
【问题描述】:

我正在尝试创建一个捆绑包,该捆绑包根据参数值设置一些解析目标实体。我在互联网上发现了类似的问题,但似乎那里的答案对我不起作用。也许我错过了一些东西。请检查我哪里出错了!

这是我在 bundle 类中的构建方法:

public function build(ContainerBuilder $container)
{
    parent::build($container);
    $container->addCompilerPass(new ResolveTargetEntitiesCompilerPass());
}

这是编译过程中的过程方法:

public function process(ContainerBuilder $container)
{
    $def = $container->findDefinition('doctrine.orm.listeners.resolve_target_entity');
    $def->addMethodCall('addResolveTargetEntity', array(
        'Test\BaseBundle\Entity\ContentType', $container->getParameter('test_base.content_type_entity_class'), array()
    ));
    $def->addMethodCall('addResolveTargetEntity', array(
        'Test\BaseBundle\Entity\Path', $container->getParameter('test_base.path_entity_class'), array()
    ));
}

据我所知,这就是我所需要的,但我得到 Doctrine\Common\Persistence\Mapping\MappingException 消息类 Test\BaseBundle\Entity\ContentType 不存在。

编辑:

在这种情况下,ContentType 是一个接口。这是我作为 test_base.content_type_entity_class 参数传递的类:

namespace Test\BaseExampleBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Test\BaseBundle\Entity\ContentType as ContentTypeInterface;

/**
 * ContentType
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class ContentType implements ContentTypeInterface
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="action", type="string", length=255)
     */
    private $action;

    /**
     * @var string
     *
     * @ORM\Column(name="codename", type="string", length=255)
     */
    private $codename;


    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @inheritdoc
     */
    public function setAction($action)
    {
        $this->action = $action;

        return $this;
    }

    /**
     * @inheritdoc
     */
    public function getAction()
    {
        return $this->action;
    }

    /**
     * @inheritdoc
     */
    public function getCodename()
    {
        return $this->codename;
    }

    /**
     * @inheritdoc
     */
    public function setCodename($codename)
    {
        $this->codename = $codename;
        return $this;
    }
}

只是为了明确 test_base.content_type_entity_class 参数的值设置为 Test\BaseExampleBundle\Entity\ContentType。

编辑:

我发现当我将至少一个条目放入教义.orm.resolve_target_entities 配置键时,它正在工作。

【问题讨论】:

  • 你检查过实体的命名空间吗?
  • 是的,我绝对确定命名空间是匹配的。
  • 自动加载器是否知道这个类(即当你像应用程序中的任何其他类一样使用它时会发现它)?如果您不确定,您可以显示使用包含该类的文件的内容、您的composer.json 文件以及您存储该类的位置。顺便说一句,您知道不需要创建这样的编译器传递,但您可以configure target entities in the application config?
  • 尝试使用'TestBaseBundle:ContentType'而不是'Test\BaseBundle\Entity\ContentType'
  • 完整的命名空间应该可以工作。请在您的问题中添加带有命名空间和映射的 ContentType 实体。

标签: symfony doctrine-orm


【解决方案1】:

我已经找到了解决方案。它在Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension::ormLoad 函数中。它根据学说版本将doctrine.orm.listeners.resolve_target_entity 服务定义标记为侦听器或订阅者。

        // BC: ResolveTargetEntityListener implements the subscriber interface since
        // v2.5.0-beta1 (Commit 437f812)
        if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) {
            $def->addTag('doctrine.event_listener', array('event' => 'loadClassMetadata'));
        } else {
            $def->addTag('doctrine.event_subscriber');
        }

所以我的解决方案是在我的编译器传递中这样做:

    if (version_compare(Version::VERSION, '2.5.0-DEV') < 0 && !$def->hasTag('doctrine.event_listener')) {
        $def->addTag('doctrine.event_listener', array('event' => 'loadClassMetadata'));
    } elseif(!$def->hasTag('doctrine.event_subscriber')) {
        $def->addTag('doctrine.event_subscriber');
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多