2013-02-21 70 views
0

我想在包含两个模块的ZF2应用程序中使用Doctrine 2,每个模块都有自己的数据库。我需要使用跨数据库连接,以便我可以将一个模块中的实体与另一个模块中的实体相关联。 Here's a UML diagram的设置。ReflectionException在从不同数据库的Doctrine映射实体时引发

我在我的第一个实体使用这种尝试(我已经去除了无关紧要的参数和use语句):

namespace Client\Entity; 

/** 
* A website. 
* 
* @ORM\Entity 
* @ORM\Table(name="users.website") 
* ... 
* @property $server 
*/ 
class Website extends BaseEntity { 

    // Other class vars ... 

    /** 
    * @ORM\ManyToOne(targetEntity="Server\Entity\Server", inversedBy="websites") 
    * @ORM\JoinColumn(name="server_id", referencedColumnName="id") 
    */ 
    protected $server; 

而这在我的服务器实体:

namespace Server\Entity; 

/** 
* A server. 
* 
* @ORM\Entity 
* @ORM\Table(name="servers.server") 
* ... 
* @property $websites 
*/ 
class Server extends BaseEntity { 

    // Other class vars ... 

    /** 
    * @ORM\OneToMany(targetEntity="Client\Entity\Website", mappedBy="server") 
    */ 
    protected $websites; 

这种映射作品完全当我创建一个新的网站实体时(通过使用DoctrineModule\Form\Element\ObjectSelect作为服务器关联的网络表单),但是当我去编辑现有网站时,抛出此ReflectionException:

类Server \实体\网站不存在

完整的堆栈跟踪can be found here。出于某种原因,当服务器实体通过与网站实体的关联进行访问时,它认为所有实体都存在于Server\Entity命名空间中,而不是Client\Entity。我需要做些什么来确保Server实体在正确的模块名称空间中查找?

的CLI命令orm:info生产:

Found 7 mapped entities: 
[OK] Server\Entity\Server 
[OK] Client\Entity\Role 
[OK] Client\Entity\Website 
[OK] Client\Entity\User 
[OK] Client\Entity\Client 
[OK] Client\Entity\Permission 
[OK] Message\Entity\Notification 

orm:validate-schema结果:

[Mapping] OK - The mapping files are correct. 
[Database] FAIL - The database schema is not in sync with the current mapping file. 

我有这个在我模块的module.config.php每一个:

'driver' => array(
    __NAMESPACE__ . '_driver' => array(
     'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver', 
     'cache' => 'array', 
     'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Entity') 
    ), 
    'orm_default' => array(
     'drivers' => array(
      __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver' 
     ) 
    ) 
) 
+0

'orm:schema-tool:update --dump-sql'会产生什么?另外:考虑到DBAL模式工具每次都在单个数据库上进行自省,所以这可能是这里的问题(已知的) – Ocramius 2013-02-21 10:39:52

+0

@Ocramius http://pastebin.com/DrtLHqsN。与之前尝试创建'users.'时存在于'servers.'数据库之前的内容稍有不同。'数据库 – hohner 2013-02-21 10:48:59

+0

@Ocramius我也用'orm:schema'成功更新了我的模式-tool:update --force',但是'validate-schema'仍然返回相同的数据库失败消息 – hohner 2013-02-21 10:56:53

回答

3

我设法修复它。在我Server\Entity\Server,我有这些getter/setter函数添加/删除网站:

public function setWebsite(Website $website) 
{ 
    $this->websites->add($website);  
} 

public function removeWebsite(Website $website) 
{ 
    $this->websites->removeElement($website); 
} 

但是你需要指定完整的命名空间作为参数:

public function setWebsite(\Client\Entity\Website $website) { ... } 

这样一个愚蠢的错误!我发现这个问题是因为我遍历了堆栈跟踪中的每个文件,并达到了试图将我的实体类中的每个方法/参数保存到代理文件(Doctrine/ORM/Proxy/ProxyFactory中的223行)的程度。 PHP)。

+0

所以代理工厂只是在抱怨错误的类名?您能否最终验证ORM主机的异常消息是否更好? – Ocramius 2013-02-22 10:51:31

+0

因为我没有指定完全限定的类名,所以它试图在Server \ Entity命名空间中实例化它们。也许应该有一种方法将getter/setter函数与关联映射(通过文件顶部的Doctrine注释声明)进行匹配,因此它知道要引用什么。异常消息总是相同的(我不知道你的意思是ORM主人)。它看起来很长,因为我正在查看_mapping注释_而不是getter/setter方法 – hohner 2013-02-22 10:57:43

+0

是的,这是因为代理工厂需要重写方法:https://github.com/doctrine/common/blob/master/ lib/Doctrine/Common/Proxy/ProxyGenerator.php#L759-L768。就我所知,自从我重写了这部分以来,ORM主(最新/最新的边缘)显示了一个自定义错误消息。只要你用'use'语句正确地导入类,Setter/getters就不需要FQCN – Ocramius 2013-02-22 11:08:23