I'm trying to use Doctrine 2 in a ZF2 application which contains two modules, each with its own database. I need to use cross-database joins so that I can associate entities from one module with entities in another. Here's a UML diagram of the setup.
I've tried using this in my first entity (I've removed irrelevant parameters and use
statements):
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;
And this in my server entity:
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;
This mapping works perfectly when I create a new website entity (via a web form which uses DoctrineModule\Form\Element\ObjectSelect
for the server association), but when I go to edit an existing website, this ReflectionException is thrown:
Class Server\Entity\Website does not exist
The full stack trace can be found here. For some reason, when the Server entity is accessed from its association with a Website entity, it thinks all of the entities exist in the Server\Entity
namespace rather than Client\Entity
. What do I need to do to make sure the Server entity looks in the correct module namespace?
The CLI command orm:info
produces:
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
But orm:validate-schema
results in:
[Mapping] OK - The mapping files are correct.
[Database] FAIL - The database schema is not in sync with the current mapping file.
I have this in each one of my module's 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'
)
)
)
I managed to fix it. In my
Server\Entity\Server
, I had these getter/setter functions for adding/removing websites:But you need to specify the full namespace as the argument:
Such a stupid mistake! I found the issue because I trawled through every file in the stack-trace and got to the point where it was attempting to save every method/argument in my Entity class to a proxy file (line 223ish in Doctrine/ORM/Proxy/ProxyFactory.php).