Symfony下的Doctrine PHPCR-ODM没有检测到映射的Document类

时间:2013-10-20 07:11:24

标签: symfony doctrine-orm symfony-cmf doctrine-phpcr

我正在尝试将PHPCR-ODM与现有的Symfony项目集成,并且无法将其(可能)检测到我映射的Document类。具体来说,我在尝试保存我的类MyDocument的文档时会出现这样的错误:

[Doctrine\Common\Persistence\Mapping\MappingException]                                                                            
The class 'Example\Common\ORM\Document\MyDocument' was not found in the chain configured namespaces Doctrine\ODM\PHPCR\Document

我的类处于一个可能很奇怪的命名空间,因为这个项目也使用了Doctrine ORM,到目前为止我刚刚为映射文档添加了一个新的空间,但是我无法想象命名空间名称的选择会影响功能。

根据文档,我已添加到我的app / autoload.php:

 AnnotationRegistry::registerFile(__DIR__.'/../vendor/doctrine/phpcr-odm/lib/Doctrine/ODM/PHPCR/Mapping/Annotations/DoctrineAnnotations.php');

我的app / config / config.yml包含以下内容(参数在parameters.yml中设置):

 doctrine_phpcr:
     session:
         backend:
             type: jackrabbit
             url: %jackrabbit_url%
         workspace: %jackrabbit_workspace%
         username: %jackrabbit_user%
         password: %jackrabbit_password%
     odm:
         auto_mapping: true

我的文档类位于src / Example / Common / ORM / Document / MyDocument.php中,如下所示:

<?php

namespace Example\Common\ORM\Document;

use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCRODM;

/**
 * @PHPCRODM\Document
 */
class MyDocument
{
  /**
   * @PHPCRODM\Id
   */
  private $id;

  /**
   * @PHPCRODM\ParentDocument
   */
  private $parent;

  /**
   * @PHPCRODM\Nodename
   */
  private $name;

  // .. etc

最后,我用来测试集成的代码在一个简单的控制台命令中,看起来像:

use Example\Common\ORM\Document\MyDocument;

// ...

$documentManager = $this->container->get('doctrine_phpcr.odm.default_document_manager');

$document = new MyDocument();
$document->setParent($documentManager->find(null, '/'));
$document->setName('ExampleName');

$documentManager->persist($document);
$documentManager->flush();

我已经验证我的MyDocument类正在被正确加载,但似乎没有以使DocumentManager知道它是映射的Document类的方式处理注释。

我的猜测是我忽略了一些简单的配置步骤,但是从重复和彻底查看PHPCR,PHPCR-ODM甚至Symfony CMF的文档,我似乎找不到任何东西。大多数例子都涉及通过Symfony CMF使用PHPCR,而且我无法找到许多(任何?)现实世界的PHPCR-ODM示例,这些示例都集成在常规的Symfony项目中。


编辑:最终解决方案

我遵循@WouterJ给出的建议,它解决了我的问题,我进一步遵循他的建议,即将一个编译器传递添加到我的Symfony包中,使其与非标准命名空间一起工作(即除了{之外的其他命令{1}})。在我的情况下,这将进入一个将在别处而不是捆绑中重用的库,所以这是合适的。

为此,我在YourBundle\Document文件中添加了一个方法,如下所示:

src/Example/Bundle/ExampleBundle/ExampleBundle.php

该代码允许将任何映射的文档类放在Example \ Common \ ODM \ Document命名空间中,它将拾取它们。此示例使用注释,但相同的模式可用于XML或YAML映射(请参阅<?php namespace Example\Bundle\ExampleBundle; use Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; class ExampleBundle extends Bundle { public function build(ContainerBuilder $container) { parent::build($container); $mappedDirectories = array( realpath(__DIR__ . '/../../Common/ODM/Document') ); $mappedNamespaces = array( 'Example\Common\ODM\Document' ); $phpcrCompilerClass = 'Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass'; if (class_exists($phpcrCompilerClass)) { $container->addCompilerPass( DoctrinePhpcrMappingsPass::createAnnotationMappingDriver( $mappedNamespaces, $mappedDirectories )); } } } 类以获取方法签名)。

我发现我还需要为此设置Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass服务,我在doctrine_phpcr.odm.metadata.annotation_reader中执行了此操作:

app/config.yml

可能有更好的方法可以做到这一点,但这足以让它对我有用。

1 个答案:

答案 0 :(得分:1)

文档应放在包的Document名称空间中,而不是ORM \ Document名称空间。

如果你真的想把它放在ORM \ Document命名空间里(这很奇怪,因为我们讨论的是ODM而不是ORM),你可以使用doctrine mapping编译器传递:http://symfony.com/doc/current/cookbook/doctrine/mapping_model_classes.html