h.kenny
h.kenny

Reputation: 31

How do I set up Doctrine 2 with multiple Entity Managers in one Project? (without Symfony/Zend)

Current Situation

I am using Doctrine 2 (without Zend and Symfony) for accessing two different MySQL databases in my Project.

I tried to create two EntityManager for each database one. The two bootstrap files are set up to use their own classes, which are located in the src-folders. They are reverse engineered with "orm:convert-mapping --from-database" and "orm:generate-entities --generate-annotations=true" and validated by "orm:validate-schema".

But the bootstrap files use the same autoload.php configuration, which is located in the vendor-folder, where composer and Doctrine 2 are installed.

The composer.json file is located in the project folder.

Currently only the last generated Schema "EntitiesAnlagenAnalyse" is working, while the first generated Schema "EntitiesPreisAnalyse" is producing an error:

PHP Fatal error: Uncaught exception

'Doctrine\Common\Persistence\Mapping\MappingException' with message 'Class 'Artikel' does not exist' in ProjectDir\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\MappingException.php:96

Stack trace:

#1 ProjectDir\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\RuntimeReflectionService.php(41): Doctrine\Common\Persistence\Mapping\MappingException::nonExistingClass('Artikel')

#2 ProjectDir\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php(281): Doctrine\Common\Persistence\Mapping\RuntimeReflectionService->getParentClasses('Artikel')

#3 ProjectDir\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php(311): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getParentClasses('Artikel')

#4 ProjectDir\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataFactory.php(78): Doctrine\Common\P in ProjectDir\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\MappingException.php on line 96


Picture of the Project Folder

For a detailed look on my Project Structure: picture of the hierarchy


Code


composer.json

{
  "require": {
    "doctrine/orm": "*"
  },
  "autoload": {
    "psr-0":
      {
        "": ["EntitiesAnlagenAnalyse/src/", "EntitiesPreisAnalyse/src/"]
      }
  }
}

EntitiesAnlagenAnalyse\bootstrap.php

<?php
// bootstrap.php
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

require_once(__DIR__."/../vendor/autoload.php");

// Create a simple "default" Doctrine ORM configuration for Annotations
$isDevMode = true;
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode, null, null, false);
$config->setProxyDir(__DIR__."/proxies");

// database configuration parameters
$conn = array(
    'driver' => 'pdo_mysql',
    'user' => '****',
    'password' => '****',
    'dbname' => '****',
);

// obtaining the entity manager
$AnlagenAnalyseManager = EntityManager::create($conn, $config);

EntitiesPreisAnalyse\bootstrap.php

<?php
// bootstrap.php
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

require_once(__DIR__."/../vendor/autoload.php");

// Create a simple "default" Doctrine ORM configuration for Annotations
$isDevMode = true;
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode, null, null, false);
$config->setProxyDir(__DIR__."/proxies");

// database configuration parameters
$conn = array(
    'driver' => 'pdo_mysql',
    'user' => '****',
    'password' => '****',
    'dbname' => '****',
);

// obtaining the entity manager
$PreisAnalyseManager = EntityManager::create($conn, $config);

Update #1

If I try to use the second EntityManager "PreisAnalyse" now, it seems like it is using the mapping of the "EntitiesAnlagenAnalyse", because it tries to get the column "t0.bezeichnung", which is only in the "Artikel" class in "EntitiesAnlagenAnalyse". But it is querying the correct database, where "bezeichnung" is not existing.

INFO: Some of the classes have the same name in both managers. So there is a Table 'Artikel' in both EntitiyManagers.

PHP Fatal error: Uncaught exception 'PDOException'

with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 't0.bezeichnung' in 'field list'' in ProjectDir\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php:104

Stack trace:

#0 ProjectDir\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php(104): PDO->query('SELECT t0.artik...')

#1 ProjectDir\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php(833): Doctrine\DBAL\Driver\PDOConnection->query('SELECT t0.artik...')

#2 ProjectDir\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php(884): Doctrine\DBAL\Connection->executeQuery('SELECT t0.artik...', Array, Array)

#3 ProjectDir\vendor\doctrine\orm\lib\Doctrine\ORM\EntityRepository.php(181): Doctrine\ORM\Persisters\Entity\BasicEntityPersister->loadAll(Array, NULL, NULL, NULL)

#4 ProjectDir\vendor\doctrine\orm\lib\Doctrine\ORM\EntityRepository.php(164): Doctrine\ORM\EntityRepository- in ProjectDir\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\AbstractMySQLDriver.php on line 71


Update #2

Now I tried to switch the strings in the array of the autoloader PSR-0 and it is working for the "PreisAnalyseManager" and for the "AnlagenAnalyseManger" but only until it reaches a query with the "Artikel" class. So it is definetely a problem with the autoloader and the new question is:

How can I define namespaces in the autoloader, so doctrine is using it the right way?

compose.json

{
  "require": {
    "doctrine/orm": "*"
  },
  "autoload": {
    "psr-0":
      {
        "": ["EntitiesPreisAnalyse/src/", "EntitiesAnlagenAnalyse/src/"]
      }
  }
}

Upvotes: 2

Views: 1066

Answers (1)

h.kenny
h.kenny

Reputation: 31

The solution was to use the PSR-4 autoloader instead of the PSR-0 and like sadok-f said in the comments below my question, I added specific namespaces and came finally to that composer.json:

{
  "require": {
    "doctrine/orm": "*"
  },
  "autoload": {
    "psr-4":
      {
        "Preis\\": "EntitiesPreisAnalyse/src/",
        "Anlagen\\": "EntitiesAnlagenAnalyse/src/"
      }
  }
}

Upvotes: 1

Related Questions