简体   繁体   中英

Difference between $em->find(..) and $em->getRepository(..)->find(..)

There is Entity

/**
 * @ORM\Entity(repositoryClass="Some\Namspace\CustomRepository")
 * @ORM\Table(name="image_type")
 */
class MyEntity{...}

and CustomRepository extends EntityRepository to override some methods like find or findAll

documentation says:

 // $em instanceof EntityManager $user = $em->find('MyProject\\Domain\\User', $id); 

Essentially, EntityManager#find() is just a shortcut for the following:

 $user = $em->getRepository('MyProject\\Domain\\User')->find($id); 

link:doctrine-orm.readthedocs.org

but my CustomRepository works only with $em->getRepository('Entities\\MyEntity')->find($id)

using $em->find('Entities\\MyEntity',$id); ignoring my overrided methods in CustomRepository


  • so is this a bug?
  • or there's a difference between this construcions?
  • how can i overide find , finAll , ... methods for my entity without overriding EntityManager?

Edit (1)

using composer:

"require": {
    "doctrine/orm": "~2.4"
},

find code:

public function find($entityName, $id, $lockMode = null, $lockVersion = null)
{
    $class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));

    if ( ! is_array($id)) {
        if ($class->isIdentifierComposite) {
            throw ORMInvalidArgumentException::invalidCompositeIdentifier();
        }

        $id = array($class->identifier[0] => $id);
    }
    ........... other ~100 lines
}

Note: the behavior explained here is for Doctrine ORM 2.3+. In 2.2 and before, it was the "reverse" one.

so is this a bug?

Nope, it's just a way to use the Entity manager "faster" without loading the repository. But behind, the repository loads the EntityManager to execute the find method.

or there's a difference between this construcions?

Performances, maybe, but actually maybe need a bench on this. But basically, it's exactly the same

What $em->find(...) does: Load a single entity by its primary key.

What $em->getRepository(...)->find(...) does:
It runs this: return $this->_em->find($this->_entityName, $id, $lockMode, $lockVersion); .
So it loads the $em->find(...) method.
So it's the same :)

how can i overide find , findAll , ... methods for my entity without overriding EntityManager?

Create a custom repository, either per-entity.

If you do this per-entity, you'll have to add the "repositoryClass" option in the "@Entity" annotation, and specify the Repository class in it, so you'll be able to override every method only for this entity.

See the docs to know more about custom repository use

You can also do it globally. Create your own EntityRepository, make it extend the Doctrine\\ORM\\EntityRepository class, and you can override the different functions.
Here is an example of an EntityRepository that is overriding the Doctrine's default repository, on Orbitale/ToolsBundle:BaseEntityRepository.php , but if you want to do this, you'll have to change the "default repository class name" in the ORM's configuration.

You don't have to override the EntityManager, it's powerful enough to be used directly as-is, and it does many things internally that should never be broken when doing fuzzy stuff in overriding it.

In doctrine 2.2 it doesn't seem to be any different - literally just a pass-through/shortcut for getRepository()->find()

http://www.doctrine-project.org/api/orm/2.2/source-class-Doctrine.ORM.EntityManager.html#348

public function find($entityName, $identifier, $lockMode = LockMode::NONE, $lockVersion = null)
{
    return $this->getRepository($entityName)->find($identifier, $lockMode, $lockVersion);
}

Thoughts:

  • What version of doctrine?
  • Any chance you have a customized EntityManager?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM