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

Leave a Reply to Ramazan Cancel reply

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