我正在尝试将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
可能有更好的方法可以做到这一点,但这足以让它对我有用。
答案 0 :(得分:1)
文档应放在包的Document名称空间中,而不是ORM \ Document名称空间。
如果你真的想把它放在ORM \ Document命名空间里(这很奇怪,因为我们讨论的是ODM而不是ORM),你可以使用doctrine mapping编译器传递:http://symfony.com/doc/current/cookbook/doctrine/mapping_model_classes.html