Using EntityManager inside Doctrine 2.0 entities

Torchello picture Torchello · Nov 5, 2010 · Viewed 28.3k times · Source

I have 2 entities: Country (id, name) and Mapping (id, object, internalId, externalId). Country and Mapping are not connected with associations (because Mapping has rows not only for country). I need to get external id for country using following conditions:

  • country.id = mapping.internalId
  • mapping.object = 'country'

So I plan to add function getExternalId() in Country

function getExternalId() {
    $em = Registry::getEntityManager();

    $mapping = $em->getRepository('Mapping')->findOneBy(array(
        'object'     => 'country',
        'internalId' => $this->getId()
    ));

    return !empty($mapping) ? $mapping->getExternalId() : false;
}

Questions:

  1. Is it good practice to use EntityManager inside entities? If no, please explain how to get external id in my case?
  2. Maybe it is possible to associate Country and Mapping using yaml files?

Thanks in advance!

Answer

Bryan M. picture Bryan M. · Nov 5, 2010

It is not a good idea to allow an entity object to rely on the entity manager. It ties the entity to the persistence layer, which was a problem Doctrine 2 was specifically trying to solve. The biggest hassle in relying on the entity manager is that it makes your model hard to test in isolation, away from the database.

You should probably be relying on service objects to handle the operations that rely on the entity manager.

// CountryService
public function getExternalId($country) {}

Additionally, you could create proxy methods on your model to call out to a service object that is set externally. A service object would be much easier to mock while testing than the entity manager would be.

$country->setService($countryService);
$country->getExternalId();

// Country
public function getExternalId()
{
   $this->_service->getExternalId($this);
}