Using EntityManager inside Doctrine 2.0 entities

≯℡__Kan透↙ 提交于 2019-11-26 06:33:52

问题


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!


回答1:


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);
}  



回答2:


This might not be the best idea, but there is a simple way to do this.

The UnitOfWork class in doctrine will hydrate any entity which implements ObjectManagerAware with the entity manager and class metadata for that entity.

All you have to do to get the entity manger in your entity is implement the interface as shown in the example below:

use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectManagerAware;

/**
 * @ORM\Entity
 */
class MyEntity implements ObjectManagerAware
{
    public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata)
    {
        $this->em = $objectManager;
    }
}

If you create a new entity rather than querying it from the database, you will need to set the entity manager manually, for example with a setter method.




回答3:


I think what you need to be using are Entity Repositories. These are detailed in the documentation, albeit a bit hard to find information on. Here is a link to the Getting Started article which documents how one would create a "repository" of 'access' functions for your entities.

Additionally here is some pseudo-code to get you started:

<?php
// repositories/CountryRepository.php

use Doctrine\ORM\EntityRepository;

class CountryRepository extends EntityRepository
{
    public function getExternalId()
    {



回答4:


A slightly cutting edge addendum to this (PHP 5.4 being at alpha 2 at time of this post) which may be of use in the future:

Here are some examples of using php 5.4 traits within Doctrine2; one of which is called active entity and provides active record style functionality within Doctrine 2 including access to the entity manager from within the entity.



来源:https://stackoverflow.com/questions/4108291/using-entitymanager-inside-doctrine-2-0-entities

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!