CRUD with entities from multiple namespaces in Symfony 2 and Doctrine

Using the CRUD generator in Symfony 2 is a breeze, as long as your entities are all in the same database and namespace. In one of my current projects we do not, and ran into problems. We finally got it working like this:

First set up your bundles. You’ll probably have one set up already, but create another one to hold the entities that represent your secondary database. In this example, the primary bundle is OurCompanyMainBundle and the secondary one is OurCompanySecondaryBundle.

Then create your database definitions in /app/config/parameters.ini:

[parameters]
database_driver = pdo_mysql
database_host = localhost
database_port =
database_name = my_main_db
database_user = mainuser
database_password = verysecretpassword

extra_database_driver = pdo_mysql
extra_database_host = localhost
extra_database_port =
extra_database_name = my_secondary_db
extra_database_user = secondaryuser
extra_database_password = alsoverysecret

Now define a new connection in your /app/cache/config.yml. You may need to add the “connections” level if you have only one database set up yet:

doctrine:
dbal:
default_connection: default
connections:
default:
driver: %database_driver%
host: %database_host%
port: %database_port%
dbname: %database_name%
user: %database_user%
password: %database_password%
charset: UTF8
extra:
mapping_types:
enum: string
driver: %extra_database_driver%
host: %extra_database_host%
port: %extra_database_port%
dbname: %extra_database_name%
user: %extra_database_user%
password: %extra_database_password%
charset: UTF8

orm:
auto_generate_proxy_classes: %kernel.debug%
entity_managers:
default:
connection: default
mappings:
OurCompanyMainBundle: ~
extra:
connection: extra
mappings:
OurCompanySecondaryBundle: ~

Congratulations! You now have two entity managers which both manage entities in their own respective databases.

If your secondary database is a legacy one, you may want to use the opportunity to generate your entities right from the database by reverse engineering the structure. This can be done pretty easily as described in the symfony2 documentation, as long as your database matches the following criteria:

  • All your tables must have a primary key.
  • If you have references to external tables, you must have set up foreign keys for them.
  • If your database has fields that Doctrine has problems with (for example enum), you must map them to another field type with mapping_type. I have done this in config.yml above, mapping all enum fields to strings.

After generating the entities and their CRUDs, you may encounter this depressing error message when accessing it:

Unknown Entity namespace alias 'OurCompanySecondaryBundle'.
500 Internal Server Error - ORMException

This error can be a bit confusing. It means your entity manager can’t see the bundle we created. To fix this, we must specify which entity manager we want to use every time we access them.

To do this, change this…

$em = $this->getDoctrine()->getEntityManager();

…to this:

$em = $this->getDoctrine()->getEntityManager('extra');

That’s it – your entities should be good to go! Enjoy managing your legacy data in the fancy new symfony2 environment! :)

This entry was posted in PHP, Troubleshooting and tagged , , , . Bookmark the permalink.

5 Responses to CRUD with entities from multiple namespaces in Symfony 2 and Doctrine

  1. nzurita says:

    Thank you for this information, I think it’s exactly what is happening to me and I didn’t find any other precise info, but errrr… where do I have to replace that string? The only place where I find a “similar” command is in /vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Generator/DoctrineEntityGenerator.php where I have


    public function generate(BundleInterface $bundle, $entity, $format, array $fields, $withRepository)
    {
    // configure the bundle (needed if the bundle does not contain any Entities yet)
    $config = $this->registry->getEntityManager(null)->getConfiguration();

    Is that null that I have to change?

    Thanks

    • Salminen says:

      Hi, thanks for the comment! You generally should never modify files in the /vendor directory as they can and will be overwritten when updating the dependencies. Make sure your config.yml is correctly set up, especially the mappings section under both entity_managers. If the mappings are correct, doctrine:generate:crud should automatically choose the correct entity manager based on the namespace shortcut name. Also make sure you have a separate bundle for the entities in your secondary database.

  2. nzurita says:

    Well, I have to add that I get the Unknown Entity namespace alias error when generating the crud so I don’t have a controller yet

  3. Ramazan says:

    Thinks for your post, it’s help me.

  4. James says:

    Had used this before but forgot to call the entity manager after using
    doctrine:generate:crud,
    and was wondering why I was getting Unknown Entity namespace alias.
    Post saved me a frustrating morning

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>